如何在长期存在的Windows窗体应用程序中管理NHibernate会话?

时间:2008-12-05 21:14:11

标签: nhibernate

我们正在使用NHibernate在复杂的模块化Windows窗体应用程序中管理我们的持久性 - 但是一个想法一直困扰着我。我们目前在启动时打开一个会话,并通过该会话打开所有对象。我担心所有加载的对象都被加载到NHibernate会话缓存中,因此它们无法被垃圾收集,最终我们将最终将整个数据库存储在内存中。

Web应用程序从未发生这种情况,因为网页请求(甚至更好的Ajax请求)代表完美的短期事务,因此可以打开和关闭会话来处理每个请求。

但是,如果我在表单应用程序中加载一个对象树然后放入屏幕上的导航窗格中,它们可能会在应用程序的生命周期内保留它们 - 并且用户可以随时点击它们,从而导致我们的需要将对象关系导航到其他对象的代码(仅在NHibernate会话中有效)。

StackOverflow读者如何在没有我描述的问题的情况下保持NHibernate的好处?

4 个答案:

答案 0 :(得分:4)

Ayende和公司通常建议每次“对话”使用一次会话。这通常会使会话生命周期持续很短的操作,因此它的行为更像是一个Web应用程序。

对于你的树箱,你可以使用Bruno的解决方案#2就好了。对象可以延迟映射。然后,每次需要访问子集时,都会启动对话并通过ISession.Lock重新连接父对象。然后在完成数据绑定时,关闭该会话。维护不需要太多开销,只需要几行任何需要进行对话的代码;如果你感觉很烦,你可以自动扩展Form和你正在使用的控件。

然后,棘手的部分是来自不同会话的并发编辑。我们不要去那里!

答案 1 :(得分:3)

当我需要一个会话时,我会打开一个会话,当我知道我不再需要它时,我会关闭它。

更具体地说,例如,如果我有一个允许我编辑客户信息的表单,我将在表单实例化时打开一个会话,并在表单关闭时关闭Session。 当我打开该表单的2个实例时,我还打开了2个会话。

答案 2 :(得分:1)

我可以看到几个选择:

  1. 急切加载对象树(我可以从documentation收集的对象树是默认的)
  2. 分离对象,拦截“click”事件,然后使用新会话从数据库加载数据。这个强迫你自己处理集合,而不是依赖于nhibernate,这可能超出了问题的范围(要求NHibernate的好处,其中之一就是集合管理)

答案 3 :(得分:1)

您可以查看我的帖子,了解如何使用uNHAddins在Windows窗体应用程序中处理每个会话的会话(uNHAddins是一个项目,其中包含由Fabio Maulo领导的NHibernate的一些附加功能,现任NH领导)

第一篇文章就是这个

http://gustavoringel.blogspot.com/2009/02/unhaddins-persistence-conversation-part.html

从那里你可以找到uNHAddins trunk的链接。