WPF应用程序中的全局实体框架上下文

时间:2010-05-20 21:35:59

标签: wpf vb.net entity-framework

我正在开发使用Entity Framework(.NET 3.5)的WPF应用程序。它访问整个地方的实体。我担心整个应用程序在实体方面的一致性。我应该在不同的视图中实例化单独的上下文,还是应该(并且这是一个很好的方法)实例可以全局访问的单个上下文?

例如,我的实体模型有三个部分,发货(包含子包和其他子内容),公司/联系人(带有子地址和电话)和磁盘规格。 Shipments和EditShipment视图访问DiskSpecs,OptionsView管理DiskSpecs(创建,编辑,删除)。如果我编辑DiskSpec,如果我有单独的上下文,我必须在ShipmentsView中检索最新的规格吗?

如果有一个整体上下文可以安全地从应用程序的其余部分检索它的对象,那么我想这是要走的路。如果是这样,该实例将放在哪里?我正在使用VB.NET,但我可以从C#翻译得相当不错。任何帮助,将不胜感激。

我只是不希望其中一个应用程序用户必须在应用程序的不同部分重新加载十几次来获取新数据。

更新

好的,所以我更改了我的应用程序,如下所示:

  1. 所有上下文都是在使用块中创建的,以便在不再需要它们之后将其丢弃。
  2. 加载后,所有实体在处理之前都会脱离上下文。
  3. MainViewModel中的一个新属性(ContextUpdated)引发一个事件,所有其他ViewModel都订阅了哪个ViewModels RefreshEntities方法。
  4. 实现这个之后,我开始收到错误,说一个实体一次只能被一个ChangeTracker引用。由于我无法确定哪个上下文仍然引用实体(不应该是任何上下文对吗?)我将对象转换为IEntityWithChangeTracker,并将SetChangeTracker设置为空(Null)。
  5. 这让当前的问题解决了: 当我在实体上空取changeTracker,然后将其附加到上下文时,它会丢失它的已更改状态,并且不会更新到数据库。但是,如果我没有使更改跟踪器为空,我无法附加。我有自己的更改跟踪代码,所以这不是问题。

    我的新问题是,你应该如何做到这一点。一个很好的例子实体查询和实体保存代码剪断将会有很长的路要走,因为我在试图获得我曾经认为是一个简单的交易工作时打我的头脑。

2 个答案:

答案 0 :(得分:6)

全局静态上下文很少是正确的答案。考虑如果在执行此应用程序期间重置数据库会发生什么 - 您的SQL连接已经消失,并且使用静态上下文的所有后续请求都将失败。

建议您找到一种方法,让您的实体上下文的生命周期缩短 - 打开它,做一些工作,处理它,......

至于将不同的对象放在同一个EDMX中,如果它们在同一个EDMX中需要它们之间存在任何关系,那几乎肯定是正确答案。

至于重新加载 - 用户永远不必这样做。在幕后,您可以打开一个新的上下文,从数据库重新加载对象的当前版本,应用他们在UI中所做的更改,然后将其保存回来。

您可能还想查看分离的实体,并在尝试保存更改并且其他人更改了数据库中的同一对象时,要注意乐观并发异常。

答案 1 :(得分:4)

好问题,科里。我大拇指。

实体框架为您提供了一个自由选择 - 您可以实例化多个上下文或只有一个静态。它在两种情况下都能很好地工作,是的,两种解决方案都是安全的。我能给你的唯一有价值的建议是:试验两者,衡量表现,延迟等,并为你选择最好的建议。这很有趣,相信我:)

如果这将是一个包含大量并发连接的真正庞大的应用程序,我会建议使用一个静态上下文或一个静态核心上下文,只需要几个额外的连接就可以支持主要的连接。但是,正如我在上面写了几行 - 这取决于你的要求哪种解决方案更适合你。

我特别喜欢你问题的这一部分:

  

我只是不想要其中一个   用户必须点击的应用程序   在不同的地方重装了十几次   应用程序的一部分以获取新数据。

WPF是一个非常非常强大的工具,基本上当用户必须按下按钮刷新数据时,它们永远消失了。 WPF为您提供了各种各样的异步,多线程工具,如Dispatcher类或后台工作程序,可以在后台轻轻刷新所需的数据。这真的很棒,因为不仅您不必担心按下各种按钮,而且后台线程也不会阻止UI,因此从用户的角度透明地刷新数据。

WPF与实体框架一起值得学习 - 请随时询问您是否还有其他问题。