Asp.Net中NHiernate的Session的管理
nhibernate中的session,在我的理解似乎就相当于数据库中连接。因为它也有open/close的方法,我没有研究nhibernate的源码,不知道这种理解是否有误?我在网上搜了很多的关于session的管理,大多都是在我需要数据库操作的时候,就opensession(),操作完后就closesession().这有点拟似如我们刚开始学习ado.net的时候,要connection对象open(),数据处理完后就close().但是这里就带来了一个弊端,因为connection的频繁的开关是非常消耗系统资源的。我记得以前在制作一个数据的录入界面的时,因为这个录入的界面数据元素比较多,而且很多dropdownlist需要在数据库中读取数据并绑定。
这样在该页面的page_load中需要调用相应对象的方法一一从数据库中检索数据绑定dropdownlist.因为我们这些对象的方法都是使用独立的connection,都有自己的connection的open和close。所以,导致这个页面一打开就需要等待好长的时间,比较慢。后来我们将这些需要绑定dropdownlist的数据通过一个数据处理成一个dataset,并将dataset中的datatable与dropdownlist绑定。这样只需要一次的connection的open/close.页面快了好多。
所以,我觉得上述的session的管理办法不是很妥当。
后来,我看了cuyahoga开源项目中他的session管理,他使用的“session-per-request”这种模式。从字面上理解就是他为每个request创建一个session,直到这个请求销毁,那么这个session也就close了。而cuyahoga他的做法和session-per-request有点不同地方就是,他为每个request都创建了一个corerepository对象,corerepository是系统所需要的数据处理服务的类。他的做法是先创建了httpmodule(nhsessionmodule)用来创建corerepository对象和销毁corerepository对象,如下:
private void context_beginrequest(object sender, eventargs e)
{
// create the repository for core objects and add it to the current httpcontext.
corerepository cr = new corerepository(true);
httpcontext.current.items.add("corerepository", cr);
}
private void context_endrequest(object sender, eventargs e)
{
// close the nhibernate session.
if (httpcontext.current.items["corerepository"] != null)
{
corerepository cr = (corerepository)httpcontext.current.items["corerepository"];
cr.closesession();
}
}
这样在每次请求的时候,会自动创建corerepository对象,当请求完毕后,就closesession(),在程序中通过httpcontext.current.items["corerepository"]就能获取corerepository对象了。
这样也就变相的管理了nhibernate中的session,也就达到了“session-per-request”的这种模式。
详细的讲解: 通过实现ihttpmodule初始化nhibernate的session
这种方式比上面的那个每次操作都需要创建session,性能和速度应该提高了不少,接着我就想,每个请求都创建session,是不是我们可以象创建connection pool一样,也创建一个session pool,这样就每次请求的时候不是直接创建session,而是在我们的session pool中拿已经创建好的session,这样效率不是更好?!