2013-03-11 51 views
9

我读过很多关于实体框架的文章(article1,article2),它多次调用DetectChanges,这使得它在处理大量数据时非常缓慢。EF Code First:很适合在SaveChanges之前调用DetectChanges?

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

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

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

// add/edit/delete entities 

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

这种方法应该工作吗?或者它可能会创建隐藏的错误?

+0

不是100%确定它是否在背景中有任何奇怪的现象,但我一直在使用类似的方法,但没有发现任何不良副作用 – Thewads 2013-03-11 16:05:15

回答

16

Arthur Vickers定义规则时DetectChanges并不需要被调用(即使不是之前SaveChangesin this blog post

到EF代码没有呼叫将离开上下文在 DetectChanges需要被调用的状态如果之前不需要叫 。

关于添加删除这些都是“EF代码”的方法,因为你要么打电话AddDelete或您的context.Entry(entity).State状态设置为AddedDeleted。所以,如果你只是循环访问一系列实体并添加或删除它们,那么根本不需要拨打DetectChanges

关于编辑我相信,它有点微妙。当您通过使用更新的实体...

context.Entry(entity).CurrentValues.SetValues(someObject); 

...或使用的DbContext财产API ...

context.Entry(entity).Property(e => e.SomeProperty).CurrentValue = someValue; 

...那么你不需要DetectChanges(甚至不在SaveChanges之前),因为这些都是再次调用“EF代码”。

如果你只需要改变一个实体的一样属性值...

entity.SomeProperty = someValue; 

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

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

而且我觉得你其实需要DetectChangesSaveChanges如果你只是遍历一些实体只有一个单呼,它们加载到或将它们连接到上下文和改变一些(标量和复杂)属性值。

如果你做更复杂的东西(也许关系改变?或其他?)你的方法可能不是安全了,因为

  1. AutoDetectChanges不会在它的方式来实现,并呼吁在许多EF方法是否会SaveChanges

  2. 是之前提到的是只有一次正确的必要in the same blog post再次证明

    如果代码使改变而改变对实体 的属性,而不是只调用添加或附加,然后,由规则2,DetectChanges 将需要被调用,至少作为SaveChanges 的一部分并且还可能在之前也可以调用 。

    (从我高亮)

不幸的是我不知道的代码在早期阶段进行比对之前SaveChanges需要调用DetectChanges时,将显示一个例子。但是因为上面的第一点,我相信这样的例子存在。

+0

这是一篇很棒的文章,谢谢。但我有点不清楚(对不起):1.为什么EF在实际保存到数据库之前需要调用DetectChanges很多次才调用DetectChanges? 2.我正在使用具有普通属性的'POCO'对象(未用'virtual'标记)。当我更改对象属性值时,EF是否静静地调用DetectChanges()? – Catalin 2013-03-12 07:31:01

+0

@RaraituL:第1点:我不知道。这就是我最后一句话的意思。第2点:不。​​当您分配属性值时,'SaveChanges'和其他一些EF方法稍后会调用'DetectChanges'。 'DetectChanges'将当前属性值与原始值(在对象上下文中作为“快照”存储)进行比较,如果值更改,属性将被标记为已修改。它被称为“基于快照的更改跟踪”。 – Slauma 2013-03-12 12:08:31

-2

可以通过DetectChanges解决的主要问题之一是当我们拥有ManyToMany关系和AutoDetectChanges=false关系时,EF中的数据持久存在。