Asp.Net大型项目实践(4)-用NHibernate保存和查询我们的业务领域对象之NHibernate的Session管理与初始化(附源码)
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);
}
} - 因为目前主要我们还是用Asp.net MVC 所以新建一个类HttpSessionStorage实现接口ISessionStorage:
代码这里我们就把NHibernate的Session的生命周期和一次Action请求( HttpContext.Current.Item)绑定在一起了,注意添加引用System.Webusing 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
}
} - 我们新建一个类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