如何在NHibernate中将Session作为一个工作单元进行管理?

时间:2013-02-22 09:08:01

标签: nhibernate unit-of-work

在Winforms和WPF中使用NHibernate几年之后,我似乎仍然错过了一个非常重要的观点,当我运行此代码片段时,这一点变得非常明显:

 ISessionFactory sf = Fluently.Configure()
                              .Database(MsSqlConfiguration.MsSql2008
                                .ConnectionString(c => c.Is(connectionString)))
                              .Mappings(x => x.FluentMappings
                                .AddFromAssemblyOf<MyClass>())
                              .BuildSessionFactory();

 for (int i = 0; i < 100; i++)
 {
     new Task(()=>
     {
         Console.WriteLine("{0}, {1}",
           i, 
           sf.OpenSession().QueryOver<MyClass>().List().Count);
     }).Start();
 }

这引起了很大的负担,我猜测。

老实说,我唯一记得读过有关会话处理的事情是:实现工作单元,它宣布了atomar会话。所以,taking a look at the pattern,我有一些顾虑/问题。

  • 延迟加载如何适应图片?如果我使用一个会话加载我的数据,然后关闭它,延迟加载将无法正常工作。所以,基本上,工作单元不能关闭/处理Session,这意味着它无限大。

  • 会话具有IsDirty等功能。如果通过单独的会话完成加载和保存对象,如何仍然可以使用它?

编辑: Oren Eini在他早期的article中表达了同样的问题。在那里,他说MicroManaging(=&gt;使用和立即Dispose)切断了NH功能,如LazyLoading和ChangeTracking。在我看来,UnitOfWork是一个Session MicroManagement模式。那么,最干净的解决方案是什么?跟踪更改自己和使用MicroManagement?单片会话(= Memleak设计)?如果与Oren的例子不同,你没有很多可以限制会话生命周期的子对话,那该怎么办?

1 个答案:

答案 0 :(得分:4)

  

延迟加载如何适应图片?

延迟加载适合一个会话的图片。加载对象后,延迟加载允许遍历对象的图形,而无需知道是否已从db加载了对象属性,并且没有急切地加载所有对象图。

似乎很完美,但有一些问题,比如“n + 1选择”

  

如果我使用一个会话加载我的数据,然后关闭它,则延迟加载将无效。

从db加载相同对象的另一个会话将不会受益于上一个会话中延迟加载的属性。

  

所以,基本上,工作单元无法关闭/处理会话,   意思是它无限大。

我不确定我是否理解这一点。我猜Session是工作单元。

  

会话具有像IsDirty这样的功能。   如果加载和保存对象是由单独的会话完成的,那么如何仍然可以使用它?

不应在单独的会话中进行加载和保存。我想这是IsDirty属性的重点。

这可能会为您提供有关NH处理的许多提示:https://softwareengineering.stackexchange.com/q/100534

希望这会有所帮助

编辑:关于你的第二个问题。通常的网络方案如下:

  1. 打开NH会议
  2. 加载NH实体
  3. 在POCO中传输NH实体属性以在UI中显示(当然,跟踪Id)
  4. 关闭NH会议
  5. 稍后(用户进行了一些更改并点击“保存”按钮),打开NH会话
  6. 加载相应的NH实体(通过其Id)
  7. 根据新的POCO字段更新NH实体
  8. 持续更改数据库
  9. 关闭NH Session
  10. 1,2和4是第一工作单元的一部分。 5,6,7,8和9是第二工作单元的一部分。