在ASP.NET中使用NHibernate

    技术2022-05-11  98

    在ASP.NET中使用NHibernate

    关键还是会话工厂的建立和NHibernate的Session的管理问题。 会话工厂仍然是使用singleton模式建立。而session管理则和Wndows Form不同:Wndows Form可以保持长连接,以获得比较好的用户体验,因而可以使用ThreadStaticAttribute或者TLS来保存session;在Web Form中使用ThreadStaticAttribute则不会如期望的那样工作,当有多个线程的时候,ThreadStaticAttribute的变量被第一个线程初始化后,其它的线程访问到的都是null,而每个HttpRequest则可能有多个线程为其服务,因而有人称ThreadStatic is evil,对于此,可以参考这个Blog。考虑到上述原因,在Web Form中使用TLS和ThreadStatic属性是不合适的,好的做法是使用HttpContext.Current.Items来共享session。我们使用HttpModule来处理之,下面是一个例子:

    using  System; using  System.Web; using  DAL; using  NHibernate; namespace  NHTest {     /// <summary>     /// NHSessionModule 的摘要说明。     /// </summary>     public class NHSessionModule : IHttpModule     {         /// <summary>         /// Default constructor.         /// </summary>         public NHSessionModule()         {}         private IEntityManager manager = null;         public void Init(HttpApplication context)         {             context.BeginRequest += new EventHandler(Context_BeginRequest);             context.EndRequest += new EventHandler(Context_EndRequest);         }         public void Dispose()         {         }         private void Context_BeginRequest(object sender, EventArgs e)         {             manager = EntityManager.CreateEntityManager();             ISession session = manager.Session as ISession;             HttpContext.Current.Items.Add("NHSession", session);             HttpContext.Current.Items.Add("Manager",manager);         }         private void Context_EndRequest(object sender, EventArgs e)         {             // Close the NHibernate session.             if ( HttpContext.Current.Items["NHSession"!= null )             {                 ISession session = HttpContext.Current.Items["NHSession"as ISession;                 if ( session != null && session.IsOpen )                 {                     session.Close();                 }             }         }     } }

     

    XML配置文件:

       < system .web >      < httpModules >        < add  type ="NHTest.NHSessionModule,NHTest"  name ="NHSessionModule"   />      </ httpModules >     </ system.web >

    上面代码中的IEntityManager 是用来执行持久化以及查询的工具类(调用NHibernate中ISession提供的方法),然后在页面中先写一个页面基类来进行Session的获取:

    using  System; using  System.Web; using  System.Web.UI; using  DAL; using  NHibernate; namespace  NHTest {     /// <summary>     /// BasePage 的摘要说明。     /// </summary>     public class BasePage : Page     {         private ISession _activeSession = null;         private IEntityManager _manager = null;         public BasePage()         {             //             // TODO: 在此处添加构造函数逻辑             //         }         public ISession ActiveSession         {             get return this._activeSession; }         }         public IEntityManager Manager         {             get return this._manager; }         }         protected override void OnInit(EventArgs e)         {             this._activeSession = HttpContext.Current.Items["NHSession"as ISession;             this._manager = HttpContext.Current.Items["Manager"as IEntityManager;             base.OnInit(e);         }     } }

     在页面中可以这么用:

    private  IEntityManager manager  =   null ; private  ISession session  =   null ; private   void  Button1_Click( object  sender, EventArgs e) {    session = base.ActiveSession;    manager = base.Manager;    IList list = manager.GetList(session, typeof ( MyBusinessType));    DataGrid1.DataSource = list;    DataGrid1.DataBind(); }

    另外请参考NHibernate的官方说明,还可以看Tobin的论述

     

    最新回复(0)