【发布时间】:2010-10-03 07:43:03
【问题描述】:
每个 ADO.NET EF 开发人员都应该了解哪些性能提示?
请在每个答案中列出每个提示,并解释为什么提示是好的(例如,通过最小化 DB 往返)。
【问题讨论】:
标签: .net entity-framework ado.net
每个 ADO.NET EF 开发人员都应该了解哪些性能提示?
请在每个答案中列出每个提示,并解释为什么提示是好的(例如,通过最小化 DB 往返)。
【问题讨论】:
标签: .net entity-framework ado.net
使用ObjectContext#GetObjectByKey() 通过键检索实体,而不是在 LINQ 查询中使用First()(或FirstOrDefault)运算符。后者每次都会访问数据库,而前者会先在 EF 缓存(具体为ObjectStateManager)中搜索实体,如果找到具有指定键的实体,则不会访问数据库。
参考文献
【讨论】:
我刚刚在分析我的应用程序中使用的 EF 代码生成的 SQL 时学到的一件事:两者之间有区别:
IEnumerable<User> users = DB.User.Where(...);
int count = users.Count();
和
IQueryable<User> users = DB.User.Where(...);
int count = users.Count();
前者生成完整查询以从User 表中检索匹配的行,并在数据传输回 EF 后完成计数。后者做了通常预期的事情:生成SELECT COUNT ... SQL,效率更高。
这很微妙,但在注意到它之后不难理解为什么:这是由于 C# 扩展方法的静态绑定性质。
解决这个问题的一个小技巧是使用“var”关键字来声明变量:
var users = DB.users.Where(...);
int count = users.Count();
这将导致“users”被声明为与“.Where”返回的相同类型;这是一个 IQueryable.
【讨论】:
假设我们有BlogPost 实体通过Author 属性引用User 实体。而不是为BlogPost.Author 属性指定完整的User 实体(这可能需要数据库往返),而是使用正确的EntityKey 初始化引用。例如:
BlogPost.AuthorReference.EntityKey = new EntityKey("EFNamespace.User", "Id", userId);
【讨论】:
更新分离的实体对象的快速简便的方法。这是一种扩展方法。
public static void AttachUpdated(this ObjectContext obj, EntityObject objectDetached)
{
if (objectDetached.EntityState == EntityState.Detached)
{
object original;
if (obj.TryGetObjectByKey(objectDetached.EntityKey, out original))
obj.ApplyPropertyChanges(objectDetached.EntityKey.EntitySetName, objectDetached);
else
throw new ObjectNotFoundException();
}
}
【讨论】: