我们已经使用EF STE已有一段时间了,但是我们的应用程序已经增长了很多,我们决定使用新的4.1 DbContext,这样我们就可以在数据层之上“扩展”一个单独的业务层,而不必使用其他类型为了它。

在对DbContext处事方式的基本评估中,我面临一个小问题。

我习惯于查询和预加载所需的相关数据,例如:

return context.Orders.Include("Detail").SingleOrDefault(ord => ord.ID == ID);


然后将返回的对象发送到UI进行修改,并在从UI返回时将更改保存到数据库。

从到目前为止的内容来看,使用以下代码很容易在DbContext中进行“更改保存”:

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


该代码的问题在于,它实际上将对象中的所有属性标记为已修改,这是我的模型中某些属性(业务规则)所不允许的。

我求助于以下解决方案(对于相对较小的需求,似乎需要大量代码!顺便说一句,不支持将修改后的属性状态更改为“未更改”):

context.Orders.Attach(order);

DbEntityEntry<Order> ordEntity = context.Entry(order);

string[] arr =
{
      ordEntity.Property(ord => ord.ID).Name,
      ordEntity.Property(ord => ord.ClientID).Name,
};

foreach (string prop in ordEntity.OriginalValues.PropertyNames)
{
      if (!arr.Contains(prop))
      {
            ordEntity.Property(prop).IsModified = true;
      }
}

context.SaveChanges();


我在此代码中遇到的问题是,“ Attach”语句引发异常,表明附加对象中的导航属性存在某种冲突,即使根本没有进行任何更改! (完全保存从数据库中检索到的对象)。
错误消息是这样的:
“已检测到对关系'OrdersDatamodel.FK_Order_Detail'的角色'Detail'的冲突更改。”

问题是:


有没有一种更“优雅”的方法来防止某些对象属性的修改?
有人知道将对象附加到上下文时会引发异常吗?


谢谢。

最佳答案

从到目前为止的内容来看,使用以下代码很容易在DbContext中进行“更改保存”:
  
  context.Entry(order).State = EntityState.Modified;


您很少需要明确设置状态。修改属性(假设它们为virtual)时,状态将自动更改为Modified,而无需进行设置。否则,DetectChanges将在您呼叫SaveChanges时进行接听。

关于c# - EF 4.1 DBContext和导航属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9341649/

10-14 18:14
查看更多