EF代码优先:在SaveChanges之前调用DetectChanges吗? [英] EF Code First: is good to call DetectChanges just before SaveChanges?
问题描述
我已阅读了几篇文章( article1 , article2 )关于实体框架它调用DetectChanges多次,这使得在使用大量数据时非常慢。
I have read few articles (article1, article2) about Entity Framework that it calls DetectChanges many times, which makes it very slow when working with large amounts of data.
我可以禁用 autoDetectChanges
当我初始化上下文,并调用 DetectChanges()
之前调用 .SaveChanges()
?
Can i, for example, disable the autoDetectChanges
when i initialize the context, and just call DetectChanges()
before calling .SaveChanges()
?
上下文是否会识别插入/更改/删除的实体?
Will the context recognize the inserted/changed/deleted entities?
var _dbContext = new ProjectContext();
_dbContext.Configuration.AutoDetectChangesEnabled = false;
// add/edit/delete entities
_dbContext.ChangeTracker.DetectChanges();
_dbContext.SaveChanges();
这种方法是否适用?或者可能会产生隐藏的错误?
Should this approach work? or it may create hidden bugs?
推荐答案
Arthur Vickers 定义了一个规则,当 DetectChanges
不需要调用(甚至不在 SaveChanges
)在这篇博客文章:
Arthur Vickers defines a rule when DetectChanges
doesn't need to be called (even not before SaveChanges
) in this blog post:
没有调用EF代码会使上下文在
DetectChanges如果不需要调用
,则需要调用。
No call to EF code will leave the context in a state where DetectChanges needs to be called if it didn’t need to be called before.
关于添加和删除这些是EF代码的方法,因为您调用添加
或删除
或者设置 context.Entry(entity).State
到的状态添加
或已删除
。所以,如果你只是循环一些文字,添加或删除它们,那么你根本不需要调用 DetectChanges
。
Regarding Add and Delete these are "EF code" methods because you either call Add
or Delete
or you set the state of context.Entry(entity).State
to Added
or Deleted
. So, if you would just loop through a bunch of entites and add or delete them then you don't need to call DetectChanges
at all.
关于修改,我相信有点更微妙。当您使用...更新实体时,您可以使用...
Regarding Edit it is, I believe, a bit more subtle. When you update entities by using either...
context.Entry(entity).CurrentValues.SetValues(someObject);
...或使用属性API DbContext
...
...or by using the property API of DbContext
...
context.Entry(entity).Property(e => e.SomeProperty).CurrentValue = someValue;
...然后你不需要 DetectChanges
(甚至不在 SaveChanges
之前),因为这些都是再次调用EF代码。
...then you don't need DetectChanges
(even not before SaveChanges
) either because these are again calls into "EF code".
如果你只是更改一个实体的属性值,如...
If you just change property values of an entity like...
entity.SomeProperty = someValue;
...然后第二条规则在同一个博客文章上面链接适用:
...then the second rule in the same blog post linked above applies:
每当非EF代码更改实体的任何属性值或
复杂对象时,都可能需要调用DetectChanges。
Any time that non-EF code changes any property value of an entity or complex object then DetectChanges may need to be called.
而且我认为你实际上只需要一个调用 DetectChanges
before SaveChanges
如果你只是循环访问一些实体,将它们加载到或附加到上下文中并更改一些(标量和复杂)属性值。
And I think you need in fact only one single call to DetectChanges
before SaveChanges
if you just loop through some entities, load them into or attach them to the context and change some (scalar and complex) property values.
如果您做的更复杂的东西(可能是关系变化或其他东西?),您的方法可能不再安全,因为
If you do more complex stuff (maybe relationship changes? or something else?) your approach might not be safe anymore because
-
AutoDetectChanges
不会按照它的方式实现,并在许多EF我中调用如果在SaveChanges
AutoDetectChanges
would not be implemented in the way it is and called in many EF methods if it would be only necessary once right beforeSaveChanges
之前只需要一次,那就是在同一篇博文中再次,
it is mentioned in the same blog post again that
如果代码对实体
的属性进行更改更改,而不是仅添加添加或附加,根据规则2,DetectChanges
将需要被调用,至少作为SaveChanges 的一部分,并且还可能在之前
。
(从我突出显示)
不幸的是我不知道在更早的阶段调用 DetectChanges
之前将显示的代码示例就在 SaveChanges
之前。但是由于上面的第1点,我确信这样的例子存在。
Unfortunately I don't know an example of code that would show when calling DetectChanges
at earlier stages than right before SaveChanges
is necessary. But because of point 1 above I am sure such examples exist.
这篇关于EF代码优先:在SaveChanges之前调用DetectChanges吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!