3

我正在为 NHibernate 的学习曲线而苦苦挣扎。

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

NHibernate 和工作单元模式

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

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

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

你的意见?

4

3 回答 3

2

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

于 2010-12-21T03:11:18.333 回答
0

If the 2nd form is a child form -- for example a modal form to edit details -- then it is participating in the same UOW as the parent and the UOW should be passed from the parent to the child, usually in the constructor.

I'm not a fan of the approach in Gabriel Schenker's article; I think it's better to use the ISession directly as a UOW implementation.

Ayende's article referenced in James' answer is good one but we do it a bit differently. For top-level forms that control their own UOW, we have a static method in Program.cs to create an ISession that is invoked in the form's constructor:

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

To make sure the ISession is properly disposed, override 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();
        }
    }

This code is in a base Form that top-level forms extend.

于 2010-12-21T18:33:03.883 回答
0

我刚刚为 NHibernate 实现了一个名为 NHUnit 的工作单元,它解决了 NHibernate 中最烦人的两个问题:使用 fetch 时的代理类和笛卡尔积。 NHUnit将您的代码与 ORM 实现分离。这意味着您只需实现两个接口即可切换到其他 ORM:IUnitIRepository. Github 上有一个简单的示例项目,向您展示如何使用NHUnit 包

于 2021-01-18T14:56:04.597 回答