每个ADO.NET EF开发人员应该了解哪些性能提示?
请在每个答案中加上每个提示并解释为什么提示是好的(例如,通过最小化数据库往返)。
答案 0 :(得分:9)
使用ObjectContext#GetObjectByKey()
按键检索实体,而不是在LINQ查询中使用First()
(或FirstOrDefault
)运算符。后者将每次都访问数据库,而前者将首先搜索实体的EF缓存(ObjectStateManager
是特定的),如果找到具有指定密钥的实体,则不会命中数据库。
参考
答案 1 :(得分:8)
我在分析应用程序中使用的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&lt;&gt;。
答案 2 :(得分:4)
假设我们通过BlogPost
属性拥有User
实体引用Author
实体。而不是为User
属性指定一个完整的BlogPost.Author
实体(可能需要数据库往返),而是使用正确的EntityKey
初始化引用。例如:
BlogPost.AuthorReference.EntityKey = new EntityKey("EFNamespace.User", "Id", userId);
答案 3 :(得分:1)
更新分离的实体对象的快速简便方法。这是一种扩展方法。
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();
}
}