Gui*_*ais 11 nhibernate asp.net-mvc session information-hiding
我目前正在构建一个ASP.NET MVC项目,NHibernate作为其持久层.
目前,已经实现了一些功能,但只使用本地NHibernate会话:访问数据库(读取或写入)的每个方法都需要使用"using()"子句实例化自己的NHibernate会话.
问题是我想利用NHibernate的延迟加载功能来提高项目的性能.
这意味着每个请求都会打开一个NHibernate会话,直到呈现视图为止.此外,必须支持同时请求(同时多个会话).
我怎样才能尽可能干净地实现这一目标?
我在网上搜索了一下,了解了每个请求的会话模式.我看到的大多数实现使用某种Http*(HttpContext等)对象来存储会话.此外,使用Application_BeginRequest/Application_EndRequest函数很复杂,因为当我只想为每个请求实例化一次会话时,它们会针对每个HTTP请求(aspx文件,css文件,js文件等)被触发.
我担心的是我不希望我的视图或控制器能够访问NHibernate会话(或者更常见的是NHibernate命名空间和代码).这意味着我不想在控制器级别处理会话,也不想在视图级别处理会话.
我有几个选择.哪一个看起来最好?
非常感谢你!
Gui*_*ais 13
好吧,经过几天的工作,我终于决定使用HttpContext.Current.Items来加载会话.
它很棒!
这就是我做到的
import System.Web
class SessionManager {
public static ISession GetSession()
var session = HttpContext.Current.Items["NHibernateSession"];
if (session == null) {
session = ...; // Create session, like SessionFactory.createSession()...
HttpContext.Current.Items.Add("NHibernateSession", session);
}
return session;
}
public static void CloseSession()
{
var session = HttpContext.Current.Items["NHibernateSession"];
if (session != null) {
if (session.IsOpen) {
session.close();
}
HttpContext.Current.Items.Remove("NHibernateSession");
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过使用此类提供的静态方法,可以获得与当前HttpContext(当前Web请求)绑定的会话(例如,在Controller中).我们需要另一段代码来在请求完成时调用CloseSession()方法.
在Global.asax.cs中:
protected void Application_EndRequest(object sender, EventArgs args)
{
NHibernateSessionManager.CloseSession();
}
Run Code Online (Sandbox Code Playgroud)
会话完成后会自动调用Application_EndRequest事件,因此可以正确关闭会话并将其处理掉.这很有用,因为否则我们必须在每个Controller中执行此操作!
| 归档时间: |
|
| 查看次数: |
6788 次 |
| 最近记录: |