4

在 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();
 }

我猜这会造成很大的负担。

老实说,我记得读过的关于会话处理的唯一内容是:实现工作单元,它声明了原子会话。所以,看看模式,我有一些顾虑/问题。

  • 延迟加载如何适合图片?如果我使用一个会话加载我的数据,然后关闭它,延迟加载将不起作用。因此,基本上,工作单元不能关闭/处置 Session,这意味着它是无限大的。

  • 会话具有诸如IsDirty. 如果加载和保存对象是由单独的会话完成的,那么这还能如何使用呢?

编辑:奥伦·艾尼(Oren Eini)在他的早期文章中已经说过与成为问题相同的事情。在那里,他说 MicroManaging(=> use 和 immediate Dispose)切断了 NH 功能,如 LazyLoading 和 ChangeTracking。不过,在我看来,UnitOfWork 是一种会话微管理模式。那么,最干净的解决方案是什么?自己跟踪更改并使用 MicroManagement?单片会话(= Memleak 设计)?如果与 Oren 的示例不同,您没有很多可以限制会话生命周期的子对话框怎么办?

4

1 回答 1

4

延迟加载如何适合图片?

延迟加载适合一个会话的图片。加载对象后,延迟加载允许遍历对象的图,而无需知道是否已经从数据库加载了对象属性,也无需急切地加载所有对象图。

看起来很完美,但也有一些问题,比如“n+1 select”

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

另一个会话,从 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 会话

1,2 和 4 是第一个工作单元的一部分。5、6、7、8 和 9 是第二个工作单元的一部分。

于 2013-02-22T09:41:08.020 回答