EF Code First:在SaveChanges之前调用DetectChanges会很好吗?

时间:2013-03-11 15:26:53

标签: entity-framework ef-code-first

我已经阅读了很多关于实体框架的文章(article1article2),它多次调用了DetectChanges,这使得处理大量数据时速度非常慢。

例如,我可以在初始化上下文时停用autoDetectChanges,并在致电DetectChanges()之前致电.SaveChanges()吗?

上下文是否会识别插入/更改/删除的实体?

var _dbContext = new ProjectContext();
_dbContext.Configuration.AutoDetectChangesEnabled = false;

// add/edit/delete entities

_dbContext.ChangeTracker.DetectChanges();
_dbContext.SaveChanges();

这种方法应该有效吗?或者它可能会产生隐藏的错误?

2 个答案:

答案 0 :(得分:17)

Arthur Vickers定义不需要调用DetectChanges的规则(即使不是SaveChanges之前)in this blog post

  

不调用EF代码会使上下文处于某种状态   如果不需要调用DetectChanges,则需要调用它   之前。

关于添加删除,这些是“EF代码”方法,因为您可以调用AddDelete,也可以设置{的状态{1}}至context.Entry(entity).StateAdded。所以,如果您只是遍历一堆entites并添加或删除它们,那么您根本不需要调用Deleted

关于编辑,我相信它更加微妙。使用...

更新实体时
DetectChanges

...或使用context.Entry(entity).CurrentValues.SetValues(someObject); ...

的属性API
DbContext

...然后您不需要context.Entry(entity).Property(e => e.SomeProperty).CurrentValue = someValue; (甚至不需要DetectChanges之前)因为这些再次调用“EF代码”。

如果您只是更改实体的属性值,例如......

SaveChanges

...然后上面链接的第二条规则in the same blog post适用:

  

任何时候非EF代码更改实体的任何属性值或   复杂的对象然后可能需要调用DetectChanges。

我认为在entity.SomeProperty = someValue; 之前只需要拨打DetectChanges一次,如果,您只需循环访问某些实体,加载它们或将它们附加到上下文中并改变一些(标量和复杂)属性值。

如果你做了更复杂的事情(可能是关系改变?或其他什么?)你的方法可能不再安全,因为

  1. SaveChanges不会按照它的方式实现,并且如果仅在AutoDetectChanges

  2. 之前需要一次,则会在许多EF方法中调用
  3. 再次提到in the same blog post

      

    如果代码对实体的属性进行了更改   而不是只调用添加或附加,然后,通过规则2,DetectChanges   需要被调用,至少作为SaveChanges 的一部分而且可能   也在之前。

    (突出显示)

  4. 不幸的是,我不知道在早期阶段调用SaveChanges时显示的代码示例,而不是DetectChanges之前的代码。但由于上述第1点,我确信存在这样的例子。

答案 1 :(得分:-2)

DetectChanges可以解决的主要问题之一是,当我们有ManyToMany关系和AutoDetectChanges=false时,会在EF中保留数据。