技术开发 频道

详解如何实践Asp.Net大型项目的开发

  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);    
}
}

 

  注意添加引用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

0
相关文章