如何更新在DbContext之外修改的实体?

如果实体在DbContext之外被更改(是一个分离的实体),我在更新实体方面遇到了一个小问题。 如果我附加修改后的实体,则其状态不会被修改。

我的代码如下所示:

var specificationToSave = GetSpecificationFromTmpStore(userSessionGuid); using (var context = DataContextFactory.GetDataContext()) { // this works for update, if I change the values inside the context while debugging // but it breaks with new entities context.Specifications.Attach(specificationToSave); // this works for insert new entities, modified entities will be saved as new entities context.Specifications.Add((specificationToSave);) context.SaveChanges(); } 

我知道NHibernate,它的方法是SaveOrUpdate。 如果更新或插入实体,NHibernate会因为值而决定。

使用EF 4.x和在DbContext之外修改的实体执行此操作的最佳做​​法是什么? 如何告诉EF该实体处于修改状态?

您还需要在附加后告诉EF该实体已被修改 。

 context.Entry(specificationToSave).State = EntityState.Modified; 

或者,您可以重新附加实体对实体进行更改,例如,请参阅带有EF 4.1和EntityState.Modified的MVC3。

编辑

您可以将generics与DbSet一起使用 – 无论是类还是方法 – 如下所示:

  public void Update(TEntity entity) { DbContext.Set().Attach(entity); DbContext.Entry(entity).State = EntityState.Modified; DbContext.SaveChanges(); } 

编辑:用于更新分离的父/子图

为了更新效率和性能不重要的简单/浅层父子关系,简单地删除所有旧孩子并重新插入新孩子是一种简单(虽然难看)的解决方案。

但是,对于更有效的方案,要求我们遍历图形,检测更改,然后添加新插入,更新现有,忽略未更改,并从Context删除已删除的项目。

Slauma 在这里展示了一个很好的例子。

您可能希望使用GraphDiff ,它可以为您完成所有这些工作!