0

我是 NHibernate 的新手,但对 EF4 很熟悉。

在一家新公司的新业务应用程序中,我们被指示使用 ASP.NET 网络表单和 NHibernate,我正在寻找开始。我计划让事情变得简单而美好,并按如下方式组织事情:

  • 调用业务层方法的代码隐藏
  • 业务层类在构造函数中采用“IRepository”引用,以促进单元测试
  • 调用存储库方法的业务层类,这些方法返回 DTO/DTO 集合
  • 存储库将隐藏/封装所有 NHibernate 的东西。

在管理会话/交易方面,它并不像我预期的那么容易:)

会话:这种方法(在 global.asax 中使用Application_BeginRequestApplication_EndRequest)看起来是最简单的方法(我认为?)....虽然我没想到必须将 NHibernate 代码放在我的 UI 层中。

现在如何使用这些会话......

这篇“最佳实践”文章建议我将这种模式用于所有NHibernate 数据访问(甚至读取):

using (ITransaction tx = Session.BeginTransaction())
{
    // execute a query, before an update, etc
    tx.Commit();
} 

所以我的问题是:

  • 在我的存储库中,我可以(我应该吗?)从 HttpContext 检索当前的 NHibernate 会话,正如(我认为)这种方法所建议的那样?对我来说似乎不对,因为它非常依赖于 UI。

(但是,这对我来说似乎比将 NHibernateISession对象传递给适当的构造函数更好,正如我在其他地方看到的那样......即在我的情况下,我必须将它从 UI 传递到业务层构造函数,然后一直到 Repository 构造函数……我希望 UI 和业务层不会意识到 NHibernate。)

  • 在我的情况下,我真的需要将所有读取都包含在事务中吗?

  • “NHibernate”事务与“”事务有什么不同System.Transactions吗?

4

1 回答 1

2

从某种意义上说,BeginRequest()/EndRequest() 并不是真正的 UI 代码,而更像是一种“应用程序框架类型的东西”,它源于在那种特定风格的应用程序中如何处理“请求”。如果您想在例如本地 Windows 应用程序中重用相同的业务层,您可能希望以不同的方式处理您的会话,因此将其完全隐藏在某种数据层中不一定是一个好主意。

您可能应该使用 NHibernate 对上下文会话的支持来跟踪每个请求的活动会话。在您的情况下,WebSessionContext。http://nhibernate.info/doc/nh/en/index.html#architecture-current-session(忘记 ManagedWebSessionContext,它已被弃用。)在此之后,您的业务/数据层将从 sessionFactory.GetCurrentSession( ),而不依赖于 UI 代码。

除了 Global.asax 中的应用程序设置代码之外,您的 UI 可能大部分都不知道 NH。您也可以将其移至其自己的 IHttpModule。如果你真的想的话,你当然可以把它隐藏在 MyDataLayer.StartSession() 后面。

您应该始终使用事务。如果不定义一个,你会得到什么?数据库仍将使用(多个)隐式事务。

NHibernate 事务和 System.Transaction 是不同的。您可以使用 TransactionScope,但在这种情况下您还必须使用 NH 的事务以避免一些问题。

于 2012-11-04T11:35:11.117 回答