NHibernate One Session Per Request简单实现
哈哈,先废话一下.
研究NHibernate应用算起来也有两个礼拜了, 自己也想总结一些自己的用法写在博客当中,但是一直都没有时间, 回家冷也就不想写了,想知道今天为啥开始写了么? 哈哈, 住在现在的地方已经快半年了, 房间一直缺把椅子,也没有时间去买(哈哈,一听就知道是借口), 今天跟同事聊天无意间提起, 说送我一把椅子,哈哈, 现在知道为啥开始写了么? 不知道的去面壁.
(切入正题)
只是打算写一些用法,具体的思路大家一起慢慢交流探讨吧,因为我也是刚学, 今天快下班的时候才测试成功, 先写出来,有问题大家在慢慢讨论.
期间主要参考了博客园NHibernate小组的两篇讨论:
1. http://home.cnblogs.com/group/topic/34139.html(这儿应该不算转载吧)
2. http://home.cnblogs.com/group/topic/34273.html
要实现One Session Per Request有以下几点需要注意:
1. 在hibernate.cfg.xml中加入一下property配置参数:
此句是制定session context的实现类, NHibernate中文文档中的说明是: “hibernate.current_session_context_class配置参数定义了应该采用哪个NHibernate.Context.ICurrentSessionContext 实现。一般而言,此参数的值指明了要使用的实现类的全名,但那三种内置的实现可以使用简写,即"managed_web", "call","thread_static", and "web", 引自 NHibernate中文文档 –> 2.3. 上下文相关的(Contextual)Session节”
2. 创建NHinbernateSessionFactory类, 我是在Dao层创建的, 这个不一定,看自己怎么认为.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
public static readonly string CurrentSessionKey = "NHibernate.Context.WebSessionContext.SessionFactoryMapKey";
/// <summary>
/// 为方便获取,增加一个CurrentSession属性
/// </summary>
public static ISession CurrentSession
{ get { return GetCurrentSession(); } }
public static ISessionFactory _sessionFactory = CreateSessionFactory();
public static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
_sessionFactory = CreateSessionFactory();
return _sessionFactory;
}
}
protected static ISessionFactory CreateSessionFactory()
{
return new Configuration()
.Configure()
.BuildSessionFactory();
}
//获取当前Session
public static ISession GetCurrentSession()
{
var ht = HttpContext.Current.Items[CurrentSessionKey] as System.Collections.Hashtable;
ISession currentSession = ht[SessionFactory] as ISession;
if (currentSession == null)
{
currentSession = SessionFactory.OpenSession();
//HttpContext.Current.Items[CurrentSessionKey] = currentSession; //此处错误
}
return currentSession;
}
//关闭Session
public static void CloseSession()
{
//var ht = HttpContext.Current.Items[CurrentSessionKey] as System.Collections.Hashtable;
//ISession currentSession = ht[SessionFactory] as ISession;
if (currentSession == null)
{
// No current session
return;
}
currentSession.Close();
HttpContext.Current.Items.Remove(CurrentSessionKey);
}
}
3. 在Global.ascx文件中给Global.asax加一个构造函数(照搬LYJ的,也可以直接在BeginRequest/EndRequst方法中写,也可以用单独的HttpModule来实现), 直接贴代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
BeginRequest += (sender, args) =>
{
var session = Data.NHinbernateSessionFactory.SessionFactory.OpenSession();
NHibernate.Context.WebSessionContext.Bind(session);
session.BeginTransaction();
};
EndRequest += (sender, args) =>
{
ISession session = NHibernate.Context.WebSessionContext.Unbind(
Data.NHinbernateSessionFactory.SessionFactory);
if (session != null)
{
if (session.Transaction != null &&
session.Transaction.IsActive)
{
session.Transaction.Commit();
}
session.Close();
}
};
}
4. 在Dao层的调用代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public IList<Domain.Entities.Customer> GetAllCustomer()
{
return Session.CreateCriteria<Domain.Entities.Customer>()
.List<Domain.Entities.Customer>();
}
至此结束, 接下来贴张测试结果的图: