我目前正在构建一个 ASP.NET MVC 项目,其中 NHibernate 作为其持久层。
目前,已经实现了一些功能,但只使用本地 NHibernate 会话:访问数据库(读取或写入)的每个方法都需要使用“using()”子句实例化自己的 NHibernate 会话。
问题是我想利用 NHibernate 的延迟加载功能来提高我的项目的性能。
这意味着在呈现视图之前,每个请求都有一个打开的 NHibernate 会话。此外,必须支持同时请求(同时多个会话)。
我怎样才能尽可能干净地做到这一点?
我在网上搜索了一下,了解了 session-per-request 模式。我看到的大多数实现都使用某种 Http*(HttpContext 等)对象来存储会话。此外,使用 Application_BeginRequest/Application_EndRequest 函数很复杂,因为当我只想为每个请求实例化一次会话时,它们会为每个 HTTP 请求(aspx 文件、css 文件、js 文件等)触发。
我担心的是我不希望我的视图或控制器能够访问 NHibernate 会话(或者,更一般地说,NHibernate 命名空间和代码)。这意味着我不想在控制器级别或视图级别处理会话。
我有几个选择。哪一个看起来最好?
- 使用在控制器操作之前和之后触发的拦截器(如在 GRAILS 中)。这些将打开和关闭会话/交易。这在 ASP.NET MVC 世界中可能吗?
- 在 Web 上下文中使用 NHibernate 提供的 CurrentSessionContext Singleton。以这个页面为例,我认为这是很有希望的,但这仍然需要控制器级别的过滤器。
- 使用 HttpContext.Current.Items 存储请求会话。再加上 Global.asax.cs 中的几行代码,可以轻松地为我提供请求级别的会话。但是,这意味着将在 NHibernate 和我的视图(HttpContext)之间注入依赖关系。
非常感谢你!