13

我读过几篇关于实体框架的文章(文章1、文章 2 ) ,它多次调用DetectChanges,这使得处理大量数据时速度非常慢。

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

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

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

// add/edit/delete entities

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

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

4

2 回答 2

21

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

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

关于AddDelete这些是“EF 代码”方法,因为您要么调用AddorDelete要么将状态设置context.Entry(entity).StateAddedor Deleted。因此,如果您只是遍历一堆实体并添加或删除它们,那么您根本不需要调用DetectChanges

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

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

...或通过使用...的属性DbContextAPI

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

...那么您也不需要DetectChanges(甚至不需要SaveChanges),因为这些又是对“EF 代码”的调用。

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

entity.SomeProperty = someValue;

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

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

DetectChanges而且我认为,SaveChanges 如果您只是遍历一些实体,将它们加载到上下文中或将它们附加到上下文并更改一些(标量和复杂)属性值,那么实际上您只需要一次调用。

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

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

  2. 在同一篇博文中再次提到

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

    (我强调)

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

于 2013-03-11T18:40:57.867 回答
-1

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

于 2015-07-16T02:01:18.560 回答