【问题标题】:NHibernate Unit Of Work - Multiple Sessions (WinForms) [closed]NHibernate 工作单元 - 多个会话(WinForms)[关闭]
【发布时间】:2023-03-24 08:21:02
【问题描述】:

我正在努力适应 NHibernate 的学习曲线。

我们目前正在移植我们的 C# Winforms 应用程序以使用 NHibernate,并且正在使用 Gabriel Schenker 详述的工作单元 (UnitOfWork)。

NHibernate and the Unit of Work Pattern

我们希望在“对话式”的基础上使用 UnitofWork。例如,当用户打开一个表单时,我们会打开一个 UnitOfWork 会话,然后保持打开状态直到表单关闭。表单只是定义业务对话的一种更简单的方式,我们可能会根据具体实现稍作更改,但对于本示例,请使用表单打开和关闭作为示例。

当我们有一个表单在另一个表单之上打开的场景时,问题就存在了。在这种情况下,我们应该有两个 UnitOfWork 操作。一个对基础表单仍然有效,一个新的 UnitOfWork 用于新表单。

我们如何实现这一点? Gabriel 提供的 UnitOfWork 功能只允许每个 UnitOfWork 一个会话?我最初的想法是将会话存储在字典中,以便可以从应用程序的任何形式或部分调用会话。

你的想法?

【问题讨论】:

    标签: c# nhibernate session unitofworkapplication


    【解决方案1】:

    在此处阅读 Ayende 在 MSDN 杂志中使用 NHibernate 构建桌面待办事项应用程序:http://msdn.microsoft.com/en-us/magazine/ee819139.aspx。他讨论了如何在胖客户端应用程序中管理多个工作单元。

    【讨论】:

      【解决方案2】:

      如果第二个表单是子表单——例如用于编辑详细信息的模式表单——那么它与父表单参与相同的 UOW,并且 UOW 应该从父表单传递给子表单,通常在构造函数。

      我不喜欢 Gabriel Schenker 文章中的方法;我觉得直接用ISession作为UOW实现比较好。

      James 的回答中引用的 Ayende 的文章不错,但我们的做法有所不同。对于控制自己的 UOW 的顶级表单,我们在 Program.cs 中有一个静态方法来创建在表单的构造函数中调用的 ISession:

      private readonly ISession _session;
      
      public frmPlayerViewer()
      {
          InitializeComponent();
          // bail out if we're in the designer
          if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
          {
                  return;
          }
          _session = Program.OpenEvtSession(FlushMode.Commit);
      }
      

      要确保正确处理 ISession,请覆盖 OnFormClosing:

          protected override void OnFormClosing(FormClosingEventArgs e)
          {
              base.OnFormClosing(e);
              if (!e.Cancel && _session != null)
              {
                  if (_session.Transaction.IsActive)
                  {
                      const string msg = "OnFormClosing with active transaction.";
                      log.Error(msg);
                      throw new Exception(msg);
                  }
                  _session.Dispose();
              }
          }
      

      此代码位于顶级表单扩展的基本表单中。

      【讨论】:

        【解决方案3】:

        我刚刚实现了一个Unit of Work for NHibernate named NHUnit,它修复了 NHibernate 中最烦人的两个问题:使用 fetch 时的代理类和笛卡尔积。 NHUnit 将您的代码与 ORM 实现分离。这意味着您只需实现两个接口即可切换到其他 ORM:IUnitIRepository。 有一个simple example project on Github,教你如何使用NHUnit package

        【讨论】:

          猜你喜欢
          • 2012-10-23
          • 2010-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多