我已经阅读了很多关于实体框架的文章(article1,article2),它多次调用了DetectChanges,这使得处理大量数据时速度非常慢。
例如,我可以在初始化上下文时停用autoDetectChanges
,并在致电DetectChanges()
之前致电.SaveChanges()
吗?
上下文是否会识别插入/更改/删除的实体?
var _dbContext = new ProjectContext();
_dbContext.Configuration.AutoDetectChangesEnabled = false;
// add/edit/delete entities
_dbContext.ChangeTracker.DetectChanges();
_dbContext.SaveChanges();
这种方法应该有效吗?或者它可能会产生隐藏的错误?
答案 0 :(得分:17)
Arthur Vickers定义不需要调用DetectChanges
的规则(即使不是SaveChanges
之前)in this blog post:
不调用EF代码会使上下文处于某种状态 如果不需要调用DetectChanges,则需要调用它 之前。
关于添加和删除,这些是“EF代码”方法,因为您可以调用Add
或Delete
,也可以设置{的状态{1}}至context.Entry(entity).State
或Added
。所以,如果您只是遍历一堆entites并添加或删除它们,那么您根本不需要调用Deleted
。
关于编辑,我相信它更加微妙。使用...
更新实体时DetectChanges
...或使用context.Entry(entity).CurrentValues.SetValues(someObject);
...
DbContext
...然后您不需要context.Entry(entity).Property(e => e.SomeProperty).CurrentValue = someValue;
(甚至不需要DetectChanges
之前)因为这些再次调用“EF代码”。
如果您只是更改实体的属性值,例如......
SaveChanges
...然后上面链接的第二条规则in the same blog post适用:
任何时候非EF代码更改实体的任何属性值或 复杂的对象然后可能需要调用DetectChanges。
我认为在entity.SomeProperty = someValue;
之前只需要拨打DetectChanges
一次,如果,您只需循环访问某些实体,加载它们或将它们附加到上下文中并改变一些(标量和复杂)属性值。
如果你做了更复杂的事情(可能是关系改变?或其他什么?)你的方法可能不再安全,因为
SaveChanges
不会按照它的方式实现,并且如果仅在AutoDetectChanges
如果代码对实体的属性进行了更改 而不是只调用添加或附加,然后,通过规则2,DetectChanges 需要被调用,至少作为SaveChanges 的一部分而且可能 也在之前。
(突出显示)
不幸的是,我不知道在早期阶段调用SaveChanges
时显示的代码示例,而不是DetectChanges
之前的代码。但由于上述第1点,我确信存在这样的例子。
答案 1 :(得分:-2)
DetectChanges
可以解决的主要问题之一是,当我们有ManyToMany
关系和AutoDetectChanges=false
时,会在EF中保留数据。