【发布时间】:2013-04-24 21:31:29
【问题描述】:
我有一个运行正常的 EF5 WPF/MVVM 解决方案。该项目是一个订单输入系统,但加载订单会加载许多相关项目,因此上下文用于跟踪所有更改,然后将其保存,因此上下文是长期存在的。如果用户 A 加载了一个订单并且不对其进行任何操作,然后用户 B 加载了该订单并对其进行了更新,那么我有一个刷新按钮,旨在让用户 A 更新陈旧的数据。不幸的是,我似乎无法让 EF5 忽略缓存。我最初认为这会起作用:
_trackingContext.GetObjectContext().Refresh(RefreshMode.StoreWins, theOrders);
List<OrderLineItem> line_items = theOrders.SelectMany(x => x.OrderLineItems).ToList();
_trackingContext.GetObjectContext().Refresh(RefreshMode.StoreWins, line_items);
GetObjectContext() 只是一个包装器
public ObjectContext GetObjectContext()
{
return (this as IObjectContextAdapter).ObjectContext;
}
原来这不会更新数据。所以我想也许我必须更改合并选项,所以我添加了
var set = _trackingContext.GetObjectContext().CreateObjectSet<OrderLineItem>();
set.MergeOption = MergeOption.OverwriteChanges;
我也尝试过 Orders(并使用 PreserveChanges 选项),但没有任何效果。最终,我只是求助于处理和重新创建上下文,然后重新创建搜索选择,但似乎这应该是矫枉过正。是否有一些更简单的方法可以让 EF5 使用数据库中的新数据更新任何陈旧数据?
更新
好的 - 事实证明这是一个测试方法问题。在看到@jure 的回复并实施它,并让它出现不起作用后,我终于变得聪明了。我爆发了 SQL Profiler。幕后发生了正确的事情,但我没有做正确的事情来更新视图。一旦我这样做了,我的原始代码就起作用了。
【问题讨论】:
-
这可能就是你要找的...stackoverflow.com/questions/1746941/objectcontext-refresh(或者如果你想刷新所有内容...msdn.microsoft.com/en-us/library/bb503718.aspx)
-
只是不要使用寿命长的上下文。您的问题只是您将面临的问题之一。
-
我现在经常看到这个建议,但在我看来,如果我希望 EF 在订单输入过程中管理所有相关记录,我必须保持上下文处于活动状态(这是一个桌面应用程序)。似乎 EF 的很多价值在于让它管理相关的数据图。也许我错过了一些基本知识,即如何从 EF 中获得所有状态管理的短暂上下文。
-
@Basic 我看过其他 SO 帖子,但使用
GetObjectStateEntries()的方法不起作用。我之前也阅读过 MSDN 文档,这就是为什么我认为Refresh(RefreshMode.StoreWins)会做到这一点但没有这样的运气。 -
Re: 使用短暂的上下文,使用其他对象来存储将构成您的订单的内容,直到您准备好进行更改,然后一次性应用它们。我的经验主要是在 Web 应用程序中,但在这种情况下,我将使用描述订单的 DTO,然后使用
Update()方法获取 DTO、查找适当的记录、应用更新和提交。这允许您将数据层与 UI 分开。
标签: c# entity-framework concurrency