我们已经使用 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’的角色‘详细信息’的更改发生冲突。”
问题是:
- 是否有更“优雅”的方法来防止某些对象属性被修改?
- 有人知道将对象附加到上下文时引发的异常是怎么回事吗?
谢谢。
最佳答案
From what I read so far, doing the "change saving" in DbContext is easily done using code like this:
context.Entry(order).State = EntityState.Modified;
您很少需要显式设置状态。当您修改属性时,假设它们是虚拟的,状态将自动更改为已修改,而无需您进行设置。否则,DetectChanges
将在您调用 SaveChanges
期间获取此信息。
关于c# - EF 4.1 DBContext 和导航属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9341649/