NHibernate中的Session yangan

NHibernate中Session是线程不安全的,而且每次数据库操作 请求创建Session时对性能有些影响。在Windows应用中可以通过 [ThreadStatic]特性很简单的就可以实现线程安全,而在Web中可以通过将Session与用于请求HttpContext绑定实现线程安全,并且用户当前请求时只有一个Session。代码如下:
  ISessionManage.cs
  using System;
  using NHibernate;
  namespace Commercial.Jwsoft.Framework.Persistence.SessionManage
  {
   /// <summary>
   /// 功能:主要用于封装第三方类库操作数据库的Session类,现主要用于封装NHibernate中的Session
   /// </summary>
   public interface ISessionManage
   {
   /// <summary>
   /// 获取Session的一个实例
   /// </summary>
   /// <returns>返回实现NHibernate.ISession接口的类</returns>
   ISession Get();
   /// <summary>
   /// 设置Session的一个实例
   /// </summary>
   /// <param name="session">实现NHibernate.ISession接口的类</param>
   void Set(ISession session);
   }
  }
  --------------------------------------------
  WebNHSession.cs
  using System;
  using System.Web;
  using NHibernate;
  namespace Commercial.Jwsoft.Framework.Persistence.SessionManage
  {
   /// <summary>
   /// 功能:此类用于Web应用,NHibernate提供的Session有两个缺陷:
   /// 一方面是线程不安全的,另一方面每次数据库操作创建一个Session对程序性能有影响。
   /// 因此通过将Session绑定到HttpContext上,这样每个用户具有唯一的一个Session,而且
   /// 在用户的请求结束后关闭Session并自己释放掉。
   /// </summary>
   public class WebNHSession : ISessionManage
   {
   public WebNHSession()
   {
   }
   /// <summary>
   /// 获取存储到HttpContext中的实现NHibernate.ISession接口的类实例
   /// </summary>
   /// <returns>实现NHibernate.ISession接口的类实例,当用户之前没有调用Set方法会返回Null</returns>
   public ISession Get()
   {
   return (ISession)HttpContext.Current.Items[SessionConfigManage.SessionSourceItemName];
   }
   /// <summary>
   /// 存储实现NHibernate.ISession接口的类实例到HttpContext中
   /// </summary>
   /// <param name="session">实现NHibernate.ISession接口的类实例</param>
   public void Set(ISession session)
   {
   if (session != null)
   {
   HttpContext.Current.Items.Add(SessionConfigManage.SessionSourceItemName, session);
   }
   else
   {
   HttpContext.Current.Items.Remove(SessionConfigManage.SessionSourceItemName);
   }
   }
   }
  }
  ---------------------------------------------
  WinFormNHSession.cs
  using System;
  using NHibernate;
  namespace Commercial.Jwsoft.Framework.Persistence.SessionManage
  {
   /// <summary>
   /// 功能:此类用于Windows应用,NHibernate提供的Session有两个缺陷:
   /// 一方面是线程不安全的,另一方面每次数据库操作创建一个Session对程序性能有影响。
   /// 因此通过线程变量获取一个NHibernate Session的多个线程安全的实例,而且线程变量使用后即释放掉。
   /// </summary>
   public class WinFormNHSession : ISessionManage
   {
   [ThreadStatic]
   private static ISession _threadSession = null;
   public WinFormNHSession()
   {
   }
   /// <summary>
   /// 获取存储到线程变量中的实现NHibernate.ISession接口的类实例
   /// </summary>
   /// <returns>实现NHibernate.ISession接口的线程安全的类实例,当用户之前没有调用Set方法会返回Null</returns>
   public ISession Get()
   {
   if (_threadSession != null)
   {
   if (_threadSession.IsConnected)
   {
   _threadSession.Reconnect();
   }
   }
   return _threadSession;
   }
   /// <summary>
   /// 存储实现NHibernate.ISession接口的类实例到线程变量中
   /// </summary>
   /// <param name="session">实现NHibernate.ISession接口的类实例</param>
   public void Set(ISession session)
   {
   if (_threadSession.IsConnected)
   {
   session.Disconnect();
   }
   _threadSession = session;
   }
   }
  }
  ----------------------------------------------
  SessionFactory.cs
  using System;
  using System.Runtime.Remoting;
  using NHibernate;
  namespace Commercial.Jwsoft.Framework.Persistence.SessionManage
  {
   /// <summary>
   /// 功能:管理多个实现ISessionManage接口的类工厂,根据读取的要加载的类名称信息,进行动态的创建Session
   /// </summary>
   public class SessionFactory
   {
   private static ISession session = null;
   private static ISessionManage sessionManage = null;
  
   static SessionFactory()
   {
   Init();
   }
   /// <summary>
   /// 获取实现NHibernate.ISession接口的Session实例
   /// </summary>
   /// <returns>返回实现NHibernate.ISession接口的类实例</returns>
   public static ISession GetSession()
   {
   session = sessionManage.Get();
  
   if (session == null)
   {
   session = NHibernateSession.GetNHibernateSession();
   sessionManage.Set(session);
   }
   return session;
   }
   private static void Init()
   {
   System.Reflection.Assembly ass = System.Reflection.Assembly.Load(SessionConfigManage.AssemblyName);
   sessionManage = (ISessionManage)ass.CreateInstance(SessionConfigManage.SessionSourceItemName);
   }
   }
  }
  ----------------------------------------------
  NHibernateSession.cs
  using System;
  using System.Data;
  using System.Collections.Generic;
  using System.Text;
  using NHibernate;
  using NHibernate.Cfg;
  namespace Commercial.Jwsoft.Framework.Persistence.SessionManage
  {
   /// <summary>
   /// 功能:加载嵌入资源(Xml配置文件),打开一个SessionFactory,获取NHibernate的Session实例
   /// </summary>
   public class NHibernateSession
   {
   private static Configuration cfg = null;
   private static ISessionFactory sessionFactory = null;
   static NHibernateSession()
   {
   cfg = new Configuration().Configure();
   sessionFactory = cfg.BuildSessionFactory();
   }
   /// <summary>
   /// 获取NHibernate的Session实例
   /// </summary>
   /// <returns></returns>
   public static ISession GetNHibernateSession()
   {
   return sessionFactory.OpenSession();
   }
   }
  }
  ---------------------------------------------
  SessionConfigManage.cs
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Configuration;
  namespace Commercial.Jwsoft.Framework.Persistence.SessionManage
  {
   /// <summary>
   /// 功能:根据类库的应用环境不同(Windows应用还是Web应用),动态创建类实例
   /// 日期:2006-08-24
   /// 作者:郭少宏
   /// </summary>
   public class SessionConfigManage
   {
   private const string SESSION_ITEM_NAME = "SessionItemName";
   private static object _locker = new object();
   private static string _sessionItemName = string.Empty;
   private static string _assemblyName = string.Empty;
   static SessionConfigManage()
   {
   string configString = ConfigurationManager.AppSettings[SESSION_ITEM_NAME];
   string[] arr = configString.Split(',');
   _sessionItemName = arr[0];
   _assemblyName = arr[1];
   }
   /// <summary>
   /// 获取配置文件中名为SESSION_ITEM_NAME配置节的信息,记录的要加载的SessionManage的类全称
   /// </summary>
   /// <returns>实现ISessionManage接口的类的名称</returns>
   public static string SessionSourceItemName
   {
   get
   {
   lock (_locker)
   {
   return _sessionItemName;
   }
   }
   }
   /// <summary>
   /// 获取配置文件中名为SESSION_ITEM_NAME配置节的信息,记录的要加载的SessionManage的类全称
   /// </summary>
   /// <returns>实现ISessionManage接口的类的程序集名称</returns>
   public static string AssemblyName
   {
   get
   {
   lock (_locker)
   {
   return _assemblyName;
   }
   }
   }
   }
  }
  在Web.Config文件中的配置节如下:
  <appSettings>
   <!---->
   <!--在Web应用中加载的获取Session的类名称-->
   <add key="SessionItemName" value="Commercial.Jwsoft.Framework.Persistence.SessionManage.WebNHSession,JWFramework"/>
   <!--在Windows应用中加载的获取Session的类名称-->
   <!--<add key="SessionItemName" value="Commercial.Jwsoft.Framework.Persistence.SessionManage.WinFormNHSession,JWFramework"/>-->
   </appSettings>
  在Global.asax中添加如下代码:
  /// <summary>
   /// 当用户断开请求时用来关闭用户请求的Session的连接
   /// </summary>
   /// <param name="sender"></param>
   /// <param name="e"></param>
   void Session_End(object sender, EventArgs e)
   {
   NHibernate.ISession session = Commercial.Jwsoft.Framework.Persistence.SessionManage.SessionFactory.GetSession();
   if (session != null)
   {
   session.Close();
   }
   }
原文地址:https://www.cnblogs.com/xlx0210/p/1538403.html