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

Cat*_*lin 9 entity-framework ef-code-first

我看了几篇文章(第一条,第二条关于实体框架,它调用DetectChanges很多次,处理大量数据的工作时,这使得它很慢).

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

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

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

// add/edit/delete entities

_dbContext.ChangeTracker.DetectChanges();
_dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

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

Sla*_*uma 17

在这篇博文中,Arthur Vickers定义了一个DetectChanges不需要调用的规则(甚至不需要调用SaveChanges):

如果不需要先调用,则不调用EF代码会使上下文处于需要调用DetectChanges的状态.

关于添加删除这些是"EF代码"方法,因为您要么调用Add或者Delete将状态设置context.Entry(entity).StateAddedDeleted.所以,如果你只是遍历一堆entites并添加或删除它们,那么你根本不需要打电话DetectChanges.

关于编辑,我相信它更微妙一些.当您使用任一更新实体时...

context.Entry(entity).CurrentValues.SetValues(someObject);
Run Code Online (Sandbox Code Playgroud)

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

context.Entry(entity).Property(e => e.SomeProperty).CurrentValue = someValue;
Run Code Online (Sandbox Code Playgroud)

...然后你不需要DetectChanges(甚至不需要SaveChanges)因为这些再次调用"EF代码".

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

entity.SomeProperty = someValue;
Run Code Online (Sandbox Code Playgroud)

...然后,上面链接的同一博客文章中的第二条规则适用:

每当非EF代码更改实体或复杂对象的任何属性值时,可能需要调用DetectChanges.

而且我觉得你其实只需要一个单一的电话DetectChanges之前SaveChanges ,如果通过一些实体你只是循环,它们加载到或将它们连接到上下文和改变一些(标量和复杂)的属性值.

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

  1. AutoDetectChanges 不会以它的方式实现并在许多EF方法中调用,如果它只需要在之前一次 SaveChanges

  2. 在同一篇博再次提到

    如果代码对实体的属性进行了更改而不是仅调用Add或Attach,那么,根据规则2,需要调用DetectChanges,至少作为SaveChanges的一部分,也可能在此之前调用.

    (突出显示)

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