您的位置:首页 > 产品设计 > UI/UE

NHibernate 如何对session管理,实现lazy=true

2013-03-05 13:27 330 查看
http://www.cnblogs.com/kenkofox/archive/2009/08/08/1541669.html

Nhibernate session管理。以前用过Hibernate,由于当时我不是主要负责持久层,所以对Hibernate不是很熟悉,但记得当时session管理没有什么问题。但是NHibernate就出现了一个问题。如果每次进行持久化操作都open一次session然后close一次session,那么将不能使用lazy这个机制。运行时会报错“session已关闭”之类的提示。

怎么解决呢?我查了一些文章得到以下结论。

两个方法:

1.自己写一个sessionFactoryHelper,里边建一个getCurrentSession方法,第一次就建一个session丢到HttpContext里边,基本不用关闭,等服务器自己销毁
http://www.developer.com/open/article.php/10930_3709346_4
2.在<httpModules>里边加入一个类,分别加入一个BeginRequest的Handler和EndRequest的Handler。使用的是Nhibernate对session绑定到request里边的机制。
http://hugh-lin.javaeye.com/blog/167730
本人在实践过程中,尝试了第二种方法。但使用Nhibernate的绑定时,出错,由于对NHibernate不熟悉,所以就完全不知道怎么解决。最后只能考虑结合第一个方法来创新一下。

最后解决过程如下:

1.建立一个NHibernateHelper这样的一个类,用于创建SessionFactory和创建session等工作。代码如下。其中实现IHttpModule接口是为了加入到Web初始化节点中,使得每次有request的时候,都会执行Application_BeginRequest和Application_EndRequest两个函数。一个是在request来的时候,打开session,放到上下文中,然后responce之前把session关闭。



using System;

using System.Web;

using NHibernate.Context;

using NHibernate;

using NHibernate.Cfg;

namespace DAL

{

/// <summary>

/// 主要用于管理session的Nhibernateclass

/// </summary>

public class NHibernateHelper : IHttpModule

{

private const string sessionKey = "nhibernate.current_session";

private static readonly ISessionFactory sessionFactory;

static readonly object padlock = new object();

/// <summary>

/// 初始化,建立只读的sessionfactory

/// </summary>

static NHibernateHelper()

{

sessionFactory = BuildSessionFactory("Model");

}

private static ISessionFactory BuildSessionFactory(string AssemblyName)

{

NHibernate.Cfg.Configuration cfg = new Configuration();

cfg.AddAssembly(AssemblyName);

return cfg.BuildSessionFactory();

}

/// <summary>

/// 初始化操作,在会话开始请求和会话结束请求事件处理中加上自定义的Application_BeginRequest和Application_EndRequest事件

/// </summary>

/// <param name="context"></param>

public void Init(HttpApplication context)

{

context.BeginRequest += new EventHandler(Application_BeginRequest);

context.EndRequest += new EventHandler(Application_EndRequest);

}

public void Dispose()

{

}

/// <summary>

/// 在一次会话请求开始的时候初始化当前的Httpcontext的session

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void Application_BeginRequest(object sender, EventArgs e)

{

HttpContext context = HttpContext.Current;

ISession currentSession= sessionFactory.OpenSession();

context.Items[sessionKey] = currentSession;

}

/// <summary>

/// 在服务器端返回消息前,关闭当前httpcontext的session

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void Application_EndRequest(object sender, EventArgs e)

{

CloseSession();

}

/// <summary>

/// 获取当前请求会话请求

/// </summary>

/// <returns></returns>

public static ISession GetCurrentSession()

{

HttpContext context = HttpContext.Current;

ISession currentSession = (ISession)context.Items[sessionKey];

if (currentSession == null)

{

currentSession = sessionFactory.OpenSession();

context.Items[sessionKey] = currentSession;

}

return currentSession;

}

/// <summary>

/// 统一的关闭session操作

/// </summary>

public static void CloseSession()

{

HttpContext context = HttpContext.Current;

ISession currentSession = (ISession)context.Items[sessionKey];

if (currentSession == null)

{

// No current session

return;

}

currentSession.Close();

context.Items.Remove(sessionKey);

}

}

}

2.要在Web.config中加入节点,使得web初始化的时候,初始化上边这个helper

<httpModules>

<add name="NHibernateHelper" type="AssemblyName.NHibernateHelper" />

</httpModules>

3.使用的时候只需要调用helper,每次都getCurrentSession得到session。OK,完成……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: