Master-Detail视图与ORM,工作单元和存储库模式相结合

时间:2012-03-13 15:16:52

标签: c# .net nhibernate design-patterns architecture

我不确定如何最好地结合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 然而,这种方法有几个重要的缺点:

  1. 我的代码中充斥着using(var uow = uowFactory.StartNew())
  2. 没有乐观的锁定正在发生。如果其他人改变了数据库中的相同项目,他的更改将被无声地覆盖。
  3. 需要两次数据库匹配才能更新项目而不是一次。
  4. 这使我得出结论,我的UoW的实施是有缺陷的。

    我考虑过改变实现,以便UoW和Repository之间的关系被颠倒过来。这意味着IoC会将一个Repository注入ViewModel而不是UnitOfWorkFactory。 Repository现在是NHibernate的ISession的功能等价物。存储库可以启动一个新的UoW,它现在与数据库事务相同 这与我的主/细节情况相符,但它不支持通常用作工作单元的同义词的“商业交易”的概念,例如,跨越多个数据库事务和用户请求的逻辑事务。

    问题是:如何最好地实现两种模式工作单元和存储库在两种情况下都可用?

1 个答案:

答案 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?

What should be the lifetime of an NHibernate session?