代码之家  ›  专栏  ›  技术社区  ›  Ewan Makepeace

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

  •  10
  • Ewan Makepeace  · 技术社区  · 15 年前

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

    web应用程序永远不会发生这种情况,因为web页面请求(甚至更好的Ajax请求)代表了完美的短命事务,因此可以打开和关闭会话来处理每个请求。

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

    4 回复  |  直到 15 年前
        1
  •  4
  •   Dan Fitch    15 年前

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

    对于树型情形,可以使用Bruno的解2。对象可以延迟映射。然后,每次需要访问子集合时,都会启动一个对话并通过重新连接父集合ISession.锁. 然后,当数据绑定完成时,关闭该会话。不需要太多的开销来维护,只需要几行任何形式的代码就可以进行对话;如果您觉得很时髦,您可以扩展表单和正在使用的控件来自动执行此操作。

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

        2
  •  3
  •   Frederik Gheysels    15 年前

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

    更具体地说,例如,如果我有一个表单,它允许我编辑客户信息,那么当表单实例化时,我将打开一个会话,当表单关闭时,我将关闭会话。 当我打开了2个表单实例时,我也打开了2个会话。

        3
  •  1
  •   Bruno Lopes    15 年前

    我可以看到两种选择:

    1. documentation 是默认值)
    2. 分离对象,截获“click”事件,然后从数据库加载数据,并使用新会话。这一点迫使您自己处理收集,而不是依赖nhibernate,这可能超出了问题的范围(这要求nhibernate的好处,其中之一是收集管理)
        4
  •  1
  •   Tavo    15 年前

    你可以看看我关于如何使用uNHAddins在Windows窗体应用程序中处理每个会话的帖子(uNHAddins是一个项目,由NH现任负责人Fabio Maulo领导的NHibernate中添加了一些内容)

    第一篇文章是这样的

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

    从那里你有链接到unaddins主干。