Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NHibernate工作单元-多个会话(WinForms)_C#_Nhibernate_Session_Unitofworkapplication - Fatal编程技术网

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

C# NHibernate工作单元-多个会话(WinForms),c#,nhibernate,session,unitofworkapplication,C#,Nhibernate,Session,Unitofworkapplication,我正在为NHibernate的学习曲线而挣扎 我们目前正在移植C#Winforms应用程序以使用NHibernate,并使用Gabriel Schenker详述的工作单元(UnitOfWork) 我们希望在“对话”的基础上使用UnitofWork。例如,当用户打开表单时,我们将打开UnitOfWork会话,然后将其保持打开状态,直到表单关闭。表单只是定义业务对话的一种更简单的方法,我们可能会根据实现的不同对此稍作更改,但对于本例,请使用表单打开和关闭作为示例 当一个表单在另一个表单上打开时,问

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

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

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

当一个表单在另一个表单上打开时,问题就存在了。在这种情况下,我们应该有两个工作单元在运行。对于基础表单,一个仍处于活动状态,而对于新表单,一个新的UnitOfWork

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


您的想法?

请阅读MSDN杂志中Ayende使用NHibernate构建桌面应用程序的内容:。他讨论了如何在厚客户端应用程序中管理多个工作单元。

如果第二个表单是子表单(例如用于编辑详细信息的模式表单),则它与父表单参与相同的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();
        }
    }
这段代码是顶级表单扩展的基本形式。

我刚刚实现了一个解决了NHibernate中两个最烦人的问题:代理类和使用fetch时的笛卡尔乘积。 将代码与ORM实现分离。这意味着您可以通过实现两个接口切换到其他ORM:
IUnit
IRepository
。 这里有一个演示如何使用的工具