繁体   English   中英

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

[英]Master-Detail view in combination with ORM, Unit of Work and Repository patterns

我不确定如何最好地结合ORM实现主详细视图。 该应用程序将WPF与MVVM一起使用,并显示所有可用对象的网格以及当前所选对象的详细信息。

视图的ViewModel非常简单,它具有:

  • 一个ObservableCollection<ItemViewModel> Items ,其中ItemViewModel是视图中应该显示的域对象的ViewModel。 此属性绑定到网格。
  • 绑定到网格的SelectedItem ItemViewModel CurrentItem属性。
  • “添加新项目”,“删除所选项目”和“将更改保存到所选项目”的ICommand

我的应用程序使用NHibernate作为其ORM工具,但我不想在整个代码库中泄漏NHibernate,因此我使用“工作单元”和“存储库”模式将其抽象出来。

这些模式的NHibernate特定实现是这样的,“工作单元”在开始和结束时打开一个新的NHibernate会话和事务,提交事务并处理会话。 因此,工作单元,会话和事务的生命周期是相同的。 工作单元具有属性Repository ,该Repository使用与工作单元相同的会话,并且具有相同的生命周期。

这就是问题所在:我想在MasterDetailViewModel的构造函数中填充Items集合。 目前,我需要创建一个新的工作单元并填充该集合。 为了没有长时间运行的事务,UoW将在之后直接处置,同时处理基础会话。

现在,当用户想要保存对当前项目的更改时,我需要打开另一个UoW,从数据库中检索实体,使用ItemViewModel的当前值更新它,将其保存到数据库并处置UoW。
但是,这种方法有几个重要的缺点:

  1. 我的代码充满了using(var uow = uowFactory.StartNew())
  2. 没有乐观的锁定正在发生。 如果其他人改变了数据库中的相同项目,他的更改将被无声地覆盖。
  3. 它需要两个数据库命中来更新项而不是一个。

这使我得出结论,我的UoW的实现存在缺陷。

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

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

更改开始业务事务的位置不一定会改变其粒度。

我不确定我是否完全得到了你的例子,但是我看不出如何在每个Repository的方法中启动一个新的UoW(每次查询持久存储时)与在MasterDetailViewModel填充时启动新的UoW的方式有很大不同它的项目,以及每次保存其中一项时的另一项。

但是,正如您所建议的那样,我在ViewModel本身中注入Repository,因为UoW看起来很奇怪有一个Repository属性 - UoW不直接操作Repository,而是一个在一个上下文中使用Repository的对象 UOW。

除此之外,我认为你几乎已经确定了与短期,细粒度业务交易相关的缺点。 你无能为力。

但是还有很多其他的会话策略。 你会在本文中找到一些建议。

另见

NHibernate在桌面应用程序中的会话管理策略是什么?

什么应该是NHibernate会话的生命周期?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM