NHibernate 工作单元 - 多个会话 (WinForms)

发布于 2024-10-08 17:42:08 字数 1431 浏览 8 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

国粹 2024-10-15 17:42:08

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

Read through Ayende's Building a Desktop To-Do Application with NHibernate in MSDN Magazine here: http://msdn.microsoft.com/en-us/magazine/ee819139.aspx. He discusses how to manage multiple units of work within a thick client application.

差↓一点笑了 2024-10-15 17:42:08

如果第二个表单是子表单(例如用于编辑详细信息的模态表单),则它与父表单参与相同的 UOW,并且 UOW 应从父表单传递到子表单(通常在构造函数中)。

我不喜欢 Gabriel Schenker 文章中的方法;我认为直接使用 ISession 作为 UOW 实现更好。

詹姆斯的回答中引用的 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();
        }
    }

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

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.

妄断弥空 2024-10-15 17:42:08

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

I've just implemented a Unit of Work for NHibernate named NHUnit which fixes two of the most annoying issues from NHibernate: proxy classes and cartesian product when using fetch.
NHUnit decouples your code from the ORM implementation. This means that you can switch to other ORM by just implementing two interfaces: IUnit and IRepository.
There is a simple example project on Github to show you how to use NHUnit package.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文