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層創建的, 這個不一定,看自己怎么認為.
NHibernateSessionFactory
{
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來實現), 直接貼代碼:
Global.asax
{
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 IList<Domain.Entities.Customer> GetAllCustomer()
{
return Session.CreateCriteria<Domain.Entities.Customer>()
.List<Domain.Entities.Customer>();
}
至此結束, 接下來貼張測試結果的圖:


浙公網安備 33010602011771號