当你使用许多 POCO 实体时,判断一个实体是否被修改(即一些更新指令需要被发送到数据库)是基于 Detect Changes(探测变化)规则的。Detect Changes 是在实体被查询或附加的时候通过检测实体的当前值和存储在快照中的原始值的不同来工作的。在这篇文章中展示的技术同时适用于 通过Code First 创建的模型 和 EF 设计器创建的模型 。
默认的,EF 在以下列出的方法被调用时自动执行Detect Changes :
- DbSet.Find
- DbSet.Local
- DbSet.Remove
- DbSet.Add
- DbSet.Attach
- DbContext.SaveChanges
- DbContext.GetValidationErrors
- DbContext.Entry
- DbChangeTracker.Entries
禁用自动探测修改功能
如果你在上下文中追踪了大量的实体或者在循环中多次调用以上这些方法,那么你可能需要在循环期间通过关闭检测修改功能来得到更大的执行效率。例如:
using(var context = new BloggingContext())
{
try
{
context.Configuration.AutoDetectChangesEnabled = false;
//在循环中 多次调用
foreach(var blog in aLotOfBlogs)
{
context.Blogs.Add(blog);
}
}finally
{
context.Configuration.AutoDetectChangesEnabled = true;
}
}
不要忘记在循环之后重新启动修改探测功能——我们这里使用了try/finally 来确该功能即使在循环中抛出异常也能重新启用。
另一种禁用和重新启用修改探测功能的方式是一直关闭它并且显示的调用context.ChangeTracker.DetectChanges 或者使用频繁的使用 修改追踪代理。这两种方式都是较好的方法,但可能会在你的应用程序中造成一些微妙的bug,所以在使用过程中要注意。
来源: