WPF应用程序中短命的DbContext合理吗?

时间:2013-03-15 22:59:24

标签: wpf entity-framework dbcontext dbset

在他关于DbContext的书中,@ RowanMiller展示了如何使用DbSet.Local属性来避免1.)对数据库进行不必要的往返,以及2.)在应用程序中传递集合(使用例如ToList()创建) 24)。然后我尝试遵循这种方法。但是,我注意到从一个使用[} - block到另一个,DbSet.Local属性变为空:

ObservableCollection<Destination> destinationsList;

using (var context = new BAContext())
{ 
   var query = from d in context.Destinations …;
   query.Load();
   destinationsList = context.Destinations.Local; //Nonzero here.
}
//Do stuff with destinationsList

using (var context = new BAContext())
{ 
   //context.Destinations.Local zero here again;
   //So no way of getting the in-memory data from the previous using- block here?
   //Do I have to do another roundtrip to the database here to get the same data I wanted
   //to cache locally???
}

那么,第24页的重点是什么?如果DbSet.Local只能在using-block中使用,我怎样才能避免传递我的集合?此外,如果我使用这些短期上下文实例而不是将任何缓存数据交给其他人,那么我如何从更改跟踪中受益?因此,如果上下文应该是短暂的,以释放连接等资源,我是否可以放弃缓存?即我不能同时使用两者(短期连接但长期缓存)?所以我唯一的选择是将查询返回的结果存储在我自己的变量中,这完全是第24页的动机中不鼓励的内容吗?

我正在开发一个WPF应用程序,它可能在未来也将成为多层次的,涉及WCF。我知道朱莉娅在她的书中有这样的例子,但我目前无法访问它。我在网上找到了其他几个,例如http://msdn.microsoft.com/en-us/magazine/cc700340.aspx(旧的ObjectContext,但很好地解释了层间协作)。在那里,使用了长寿命的背景(虽然提到了缺点,但没有解决这些问题)。 这不仅仅是单个Destinations.Local丢失了,因为你肯定知道查询提取的所有其他实体也是。

[编辑]: 在Julia Lerman的书中再读一遍之后,似乎归结为EF默认情况下没有二级缓存;但是,有些人(相当多,我认为)努力,可以添加第三方缓存解决方案,如本书和MSDN,codeproject等各种文章中所述。

如果在DbContext一书中有关DbSet.Local的部分中提到过这个问题,它实际上是在使用{}块结束时被破坏的第一级缓存(我只是提出它的建议)对读者更透明)。在第一次阅读之后我得到了印象DbSet.Local总是会在第二个使用{}块返回相同的引用(Singleton样式),尽管有新的DbContext实例。

但是我仍然不确定二级缓存是否适合我的WPF应用程序(因为Julia在她的文章中提到了分布式应用程序的二级缓存)?或者是通过using {}块中的一个或一些查询将我的域模型的聚合根实例(DDD,Eric Evans)放入内存,处理DbContext并仅保存对聚合实例的引用的方法避免长期背景的方式?如果你能帮我做出这个决定,那就太好了。

http://msdn.microsoft.com/en-us/magazine/hh394143.aspx http://www.codeproject.com/Articles/435142/Entity-Framework-Second-Level-Caching-with-DbConte http://blog.3d-logic.com/2012/03/31/using-tracing-and-caching-provider-wrappers-with-codefirst/

1 个答案:

答案 0 :(得分:0)

Local property提供了“此集中所有已添加,未更改和已修改实体的本地视图”。像所有变更跟踪一样,它特定于您当前使用的上下文。

数据库上下文是一个用于加载数据和准备更改的工作空间。

如果两个用户要同时添加更改,则在保存更改之前,他们必须不知道其他更改。他们可能会放弃准备好的更改,而这些更改突然也会给其他用户带来麻烦。

数据库上下文确实应该短暂存在,但是在必要时可能比超短更长。还请注意,如果您不加载和丢弃数据,而仅添加要保存的更改,则可能不会通过短命保存资源。但这不仅与资源有关,而且与数据库上下文仍处于活动状态并已加载数据时可能改变的数据库状态有关。对于较长的生活环境,可能要记住这一点。

如果您尚不知道要立即保存到数据库中的所有相关更改,那么我建议您不要使用DB Context将更改存储在内存中,而是存储在代码的数据结构中。

您当然可以在没有活动的数据库上下文的情况下使用实体对象来这样做。如果您没有其他合适的数据类并且不想创建一个数据类,或者决定准备其中的更改更有意义,那么这是有道理的。然后,您可以使用DbSet.Attach将实体附加到数据库上下文,以在准备好后保存更改。