我不确定如何最好地结合ORM实现主详细视图。 该应用程序将WPF与MVVM一起使用,并显示所有可用对象的网格以及当前所选对象的详细信息。
视图的ViewModel非常简单,它有:
ObservableCollection<ItemViewModel> Items
其中ItemViewModel
是域对象的ViewModel,它应该是视图中的显示器。此属性绑定到网格。ItemViewModel CurrentItem
。SelectedItem
属性
ICommand
用于“添加新项目”,“删除所选项目”和“将更改保存到所选项目”。我的应用程序使用NHibernate作为其ORM工具,但我不想在整个代码库中泄漏NHibernate,因此我使用“工作单元”和“存储库”模式将其抽象出来。
这些模式的NHibernate特定实现是这样的,“工作单元”在开始和结束时打开一个新的NHibernate会话和事务,提交事务并处理会话。因此,工作单元,会话和事务的生命周期是相同的。工作单元的财产Repository
使用与工作单位相同的会话,并且具有相同的生命周期。
这就是问题所在:
我想在Items
的构造函数中填充MasterDetailViewModel
集合。目前,我需要创建一个新的工作单元并填充该集合。为了没有长时间运行的事务,UoW将在之后直接处置,同时处理基础会话。
现在,当用户想要保存对当前项目的更改时,我需要打开另一个UoW,从数据库中检索实体,使用ItemViewModel
的当前值更新它,将其保存到数据库并处理UoW
然而,这种方法有几个重要的缺点:
using(var uow = uowFactory.StartNew())
。这使我得出结论,我的UoW的实施是有缺陷的。
我考虑过改变实现,以便UoW和Repository之间的关系被颠倒过来。这意味着IoC会将一个Repository注入ViewModel而不是UnitOfWorkFactory。 Repository现在是NHibernate的ISession
的功能等价物。存储库可以启动一个新的UoW,它现在与数据库事务相同
这与我的主/细节情况相符,但它不支持通常用作工作单元的同义词的“商业交易”的概念,例如,跨越多个数据库事务和用户请求的逻辑事务。
问题是:如何最好地实现两种模式工作单元和存储库在两种情况下都可用?
答案 0 :(得分:0)
更改开始业务交易的位置不一定会改变其粒度。
我不确定我是否完全得到了您的示例,但我无法看到如何在每个Repository的方法中启动一个新的UoW(每次查询持久性存储时)与在启动新UoW时的粒度方式有很大不同MasterDetailViewModel填充其项目,并在每次保存其中一个项目时填充另一个项目。
但是,正如你所建议我将在ViewModel中注入Repository,因为对于UoW来说,拥有Repository属性似乎很奇怪 - UoW不会直接操作Repository,而是一些在 UoW。
的上下文中使用存储库的对象除此之外,我认为你几乎已经确定了与短期,细粒度业务交易相关的缺点。你无能为力。
但是还有很多其他会话策略。您可以在此article找到一些建议。
另见
What is your session management strategy for NHibernate in desktop applications?