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配置参数:

  <property name='current_session_context_class'>web</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层创建的, 这个不一定,看自己怎么认为.

 

NHibernateSessionFactory
    public class NHinbernateSessionFactory
    {
        
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; //此处错误
                //更正如下:
                WebSessionContext.Bind(session);//还是用NHibernate自带的方法将Session绑定到HttpContext.Current上.
            }
            
return currentSession;
        }

        
//关闭Session     
        public static void CloseSession()
        {
            //var ht 
= HttpContext.Current.Items[CurrentSessionKey] as System.Collections.Hashtable;
            //ISession currentSession 
= ht[SessionFactory] as ISession;
            var session = WebSessionContext.Unbind(SessionFactory); //从HttpContext.Current中卸载Session,并返回当前Session
            
if (currentSession == null)
            {
                
// No current session   
                return;
            }
            currentSession.Close();
            HttpContext.Current.Items.Remove(CurrentSessionKey);
        }
    }

 


 3.  在Global.ascx文件中给Global.asax加一个构造函数(照搬LYJ的,也可以直接在BeginRequest/EndRequst方法中写,也可以用单独的HttpModule来实现), 直接贴代码:

Global.asax
public Global()
        {
            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层的调用代码:

Dao层调用代码
public static ISession Session { get { return NHinbernateSessionFactory.CurrentSession; } }

        
public IList<Domain.Entities.Customer> GetAllCustomer()
        {
            
return Session.CreateCriteria<Domain.Entities.Customer>()
                  .List
<Domain.Entities.Customer>();
        }

 

至此结束, 接下来贴张测试结果的图:

 

posted @ 2009-12-03 22:11  DukeCheng  阅读(2983)  评论(30编辑  收藏