我们已经使用EF STEs一段时间了,但是我们的应用程序已经增长了很多,我们决定起诉新的4.1 DbContext,这样我们就可以在我们的数据层之上“发展”一个单独的业务层,而不必使用不同的类型。
在对DbContext做事方式的初步评估中,我遇到了一个小问题。
我习惯查询和预加载所需的相关数据,如:
return context.Orders.Include("Detail").SingleOrDefault(ord => ord.ID == ID);
然后将返回的对象发送到UI进行修改,并在从UI返回时将更改保存到数据库中。
从我到目前为止所读到的内容,使用以下代码轻松完成DbContext中的“更改保存”:
context.Entry(order).State = EntityState.Modified;
此代码的问题在于它实际上将对象中的所有属性标记为已修改,这是我的模型中某些属性(业务规则)不允许的。
我采用了以下解决方案(对于相对较小的要求似乎需要大量代码!BTW,不支持将修改后的属性状态更改为Unchanged):
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'的角色'详细'发生冲突变化。”
问题是:
感谢。
答案 0 :(得分:2)
从我到目前为止所读到的内容,使用以下代码轻松完成DbContext中的“更改保存”:
context.Entry(order).State = EntityState.Modified;
您很少需要明确设置状态。当您修改属性时,假设它们是virtual
,状态将自动更改为Modified
,而无需您设置它。否则,DetectChanges
会在您致电SaveChanges
期间接听此消息。