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

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,完成……

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏debugeeker的专栏

《coredump问题原理探究》Linux x86版6.5节虚函数的coredump例子

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

440
来自专栏Linux驱动

汇编指令-位置无关码(BL)与绝对位置码(LDR)(2)

位置无关码 即该段代码无论放在内存的哪个地址,都能正确运行。究其原因,是因为代码里没有使用绝对地址,都是相对地址。  位置相关码 即它的地址与代码处于的位置相关...

2467
来自专栏奇点大数据

用SparkStreaming做奇怪的事

作者:尹会生 无需授权即可转载,甚至无需保留以上版权声明 Spark Steaming 是非常著名的流式计算工具,这次用它来搞一个奇葩的需求:开发给定一个日志...

28110
来自专栏about云

hive文件存储格式:SequenceFile系统总结

问题导读 1.什么是SequenceFile? 2.如何 通过 源码实现SequenceFile压缩? 3.SequenceFile格式压缩有什么优点和缺点?...

3378
来自专栏程序员的SOD蜜

常见.NET功能代码汇总 (2)

常见.NET功能代码汇总 23,获取和设置分级缓存 获取缓存:首先从本地缓存获取,如果没有,再去读取分布式缓存 写缓存:同时写本地缓存和分布式缓存 priv...

2296
来自专栏木子昭的博客

Django"取真经"一次面向Django服务端的请求:

唐僧一行人受唐王李世民委派,携通关文牒,前往西天取经,一路斩妖除魔,经历九九八十一难,成功到达了西天大雷音寺,在僧人引导下,穿过罗汉堂,终见佛祖,佛祖接见唐僧...

2706
来自专栏分布式系统和大数据处理

Http请求处理流程

我查阅过不少Asp.Net的书籍,发现大多数作者都是站在一个比较高的层次上讲解Asp.Net。他们耐心、细致地告诉你如何一步步拖放控件、设置控件属性、编写Cod...

472
来自专栏五毛程序员

五毛的cocos2d-x学习笔记07-计时器、数据读写、文件读写

1695
来自专栏ASP.NETCore

细说ASP.NET Core与OWIN的关系

  最近这段时间除了工作,所有的时间都是在移植我以前实现的一个Owin框架,相当移植到到Core的话肯定会有很多坑,这个大家都懂,以后几篇文章可能会围绕这个说下...

682
来自专栏技术之路

Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能

说一下IHandle<T>实现多语言功能 因为Caliburn.Micro是基于MvvM的UI与codebehind分离, binding可以是双向的所以我们想...

1987

扫码关注云+社区