entity framework – 为什么显式设置实体状态为修改?

官方文档说修改一个实体,我检索一个DbEntityEntry对象,并使用属性函数或设置其状态为修改。 它使用下面的例子

Department dpt = context.Departments.FirstOrDefault(); DbEntityEntry entry = context.Entry(dpt); entry.State = EntityState.Modified; 

我不明白第二和第三个陈述的目的。 如果我要求框架中的第一条语句这样的实体,然后修改POCO

 dpt.Name = "Blah" 

如果我然后问EF到SaveChanges(),实体的状态是MODIFIED(我猜通过快照跟踪,这不是一个代理),并且更改是持久的,无需手动设置状态。 我在这里错过了什么?

在你的情况下,你确实不需要设置状态。 改变跟踪的目的是发现你已经改变了附属实体的值,并将其置于修改状态。 手动设置状态对于分离的实体(在没有更改跟踪或在当前上下文之外创build的实体加载)很重要。

如前所述,在断开实体的情况下,将实体的状态设置为Modified可能很有用。 如果只是连接断开连接的实体,它将节省往返数据库的往返时间,而不是从数据库中获取实体并修改并保存实体。

但是可以有很好的理由不要将状态设置为Modified (我确信Ladislav已经意识到这一点,但是我仍然想在这里指出)。

  1. logging中的所有字段都将被更新,而不仅仅是更改。 有更多的系统审计。 更新所有字段将导致大量混乱或要求审计机制过滤出错误的更改。

  2. 乐观并发。 由于所有字段都被更新,这可能会导致更多的冲突。 如果两个用户同时更新相同的logging,但不是相同的字段,则不需要冲突。 但是,如果他们总是更新所有字段,最后一个用户将总是尝试写入陈旧的数据。 这最多会导致一个乐观的并发exception,或在最坏的情况下导致数据丢失。

  3. 无用的更新。 实体被标记为已修改,无论如何。 未更改的实体也将触发更新。 这可能很容易发生,如果编辑窗口可以打开查看细节,并OKclosures。

所以这是一个很好的平衡。 减less往返或减less冗余。

无论如何,将状态设置为Modified的替代方法是(使用DbContext API):

 void UpdateDepartment(Department department) { var dpt = context.Departments.Find(department.Id); context.Entry(dpt).CurrentValues.SetValues(department); context.SaveChanges(); } 

CurrentValues.SetValues单个属性标记为已Modified