NHibernate的Session和Asp.Net的Session是兩碼事,大家不要混淆了。NHibernate的Session是拿來幹啥的?對用用過Linq2Sql的同學,可以把它理解成DataContext。要被持久化的對象都要放在Session裡託管。Session同時也是一個緩衝,比如在一定範圍內你通過NHibernate ,Get了一個User ,當你再次Get同樣的這個User的時候NHibernate就不會去操作資料庫,而會直接從Session緩衝中取出第一次獲得的User。
- 為了充分利用NHibernate的消極式載入和它緩衝機制,我們應該把Session的生命週期合理控制,比如在WCF應用中我們應該把Session綁定在一次通訊請求裡,在Asp.netMVC中我們最好把Session的生命週期綁定在一次Action裡。由於我們的系統設計將來會用到WCF或其他請求形式,所以我們做一個介面:
using System;
using NHibernate;
namespace Demo.HIS.FrameWork.Repository.NHb
{
public interface ISessionStorage
{
ISession Get();
void Set(ISession value);
}
}
注意添加引用NHibernate.dll,目前使用的版本是NHibernate-2.1.0
- 因為目前主要我們還是用Asp.net MVC 所以建立一個類HttpSessionStorage實現介面ISessionStorage:代碼
using NHibernate;
using System.Web;
namespace Demo.HIS.FrameWork.Repository.NHb
{
public class HttpSessionStorage : ISessionStorage
{
#region ISessionStorage 成員
public NHibernate.ISession Get()
{
return (ISession)HttpContext.Current.Items["NhbSession"];
}
public void Set(ISession value)
{
if (value != null)
{
HttpContext.Current.Items.Add("NhbSession", value);
}
}
#endregion
}
}
這裡我們就把NHibernate的Session的生命週期和一次Action請求( HttpContext.Current.Item)綁定在一起了,注意添加引用System.Web
- 我們建立一個類SessionBuilder去初始化NHibernate的Session:代碼
namespace Demo.HIS.FrameWork.Repository.NHb
{
public static class SessionBuilder
{
private static object locker = new object();
private static Configuration configuration = null;
private static ISessionFactory sessionFactory = null;
public static ISessionStorage sessionStorage { set; get; }
private static void CreateConfiguration()
{
// HibernatingRhinos.NHibernate.Profiler.Appender.NHibernateProfiler.Initialize();//查看HQL產生的SQL
//configuration = new Configuration().Configure(System.Web.HttpContext.Current.Request.PhysicalApplicationPath + "Configuration\\hibernate.cfg.xml");
configuration = new Configuration().Configure();
}
public static Configuration Configuration
{
get
{
lock (locker)
{
if (configuration == null)
{
CreateConfiguration();
}
return configuration;
}
}
set { configuration = value; }
}
internal static ISessionFactory SessionFactory
{
get
{
if (sessionFactory==null)
{
if (Configuration == null)
{
CreateConfiguration();
}
lock (locker)
{
sessionFactory = Configuration.BuildSessionFactory();
}
}
return sessionFactory;
}
}
public static ISession CreateSession()
{
ISession s = sessionStorage.Get();
if (s == null)
{
s = SessionFactory.OpenSession();
sessionStorage.Set(s);
}
return s;
}
}
}
注意configuration = new Configuration().Configure(); 這句讀取NHibernate的設定檔,設定檔的位置必須放在網站(DemoHisSite)根目錄,且命名為hibernate.cfg.xml,如果你想把這個設定檔放在別的位置或取其他名字,請看代碼裡注釋掉的那行。
NHibernate設定檔
位置:
內容:
代碼<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="hibernate-configuration"
type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory>
<property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
<property name="connection.connection_string">
User ID=dawnhis;Password=his;Data Source=dawhisdb
</property>
<property name="show_sql">true</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<property name="use_outer_join">true</property>
<property name="command_timeout">10</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="Infrastructure.Repositories"/>
</session-factory>
</hibernate-configuration>
</configuration>
具體配置節的含義,自己找資料看吧這裡就不羅嗦了
在Global.asax指定ISessionStorage具體執行個體:
代碼namespace Demo.HIS.MVC
{
public class DemoHISApplication : HttpApplication
{
protected virtual void OnStart()
{
initSessionBuilder();
}
private void initSessionBuilder()
{
SessionBuilder.sessionStorage = new HttpSessionStorage();//這裡建立Session執行個體
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
OnStart();
}
}
}
注意我這裡更改了下Global.asax的引用:
<%@ Application Inherits="Demo.HIS.MVC.DemoHISApplication" Language="C#" %>
源碼下載:HISDemo-2.rar