C# NHibernate工作单元-多个会话(WinForms)
我正在为NHibernate的学习曲线而挣扎 我们目前正在移植C#Winforms应用程序以使用NHibernate,并使用Gabriel Schenker详述的工作单元(UnitOfWork) 我们希望在“对话”的基础上使用UnitofWork。例如,当用户打开表单时,我们将打开UnitOfWork会话,然后将其保持打开状态,直到表单关闭。表单只是定义业务对话的一种更简单的方法,我们可能会根据实现的不同对此稍作更改,但对于本例,请使用表单打开和关闭作为示例 当一个表单在另一个表单上打开时,问题就存在了。在这种情况下,我们应该有两个工作单元在运行。对于基础表单,一个仍处于活动状态,而对于新表单,一个新的UnitOfWork 我们如何实现这一点?Gabriel提供的UnitOfWork功能只允许每个UnitOfWork进行一次会话?我最初的想法是将会话存储在字典中,以便可以从应用程序的任何形式或部分调用会话C# NHibernate工作单元-多个会话(WinForms),c#,nhibernate,session,unitofworkapplication,C#,Nhibernate,Session,Unitofworkapplication,我正在为NHibernate的学习曲线而挣扎 我们目前正在移植C#Winforms应用程序以使用NHibernate,并使用Gabriel Schenker详述的工作单元(UnitOfWork) 我们希望在“对话”的基础上使用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
。
这里有一个演示如何使用的工具