• Web项目下NHibernate的Session管理的解决方案 【转】


    NHibernate的Session的管理一直是个问题,在系统开发中

    如果有lazy="true",如果不对Session进行管理,会抛出以下错误:
    CODE:

    Failed to lazily initialize a collection - no session


    在Web项目下的解决方案,就是在Application_BeginRequest方法中打开Session并放入HttpContext,在Application_EndRequest方法中关闭Sesssion就可以了。

    还好,NHibernate1.2已经提供了相关的支持,如下:

    在web.config中加入以下代码
    CODE:

    <httpModules>
            <add name="CurrentSessionModule" type="NHibernate.Example.Web.CurrentSessionModule" />
        </httpModules>



    程序如下:

    CODE:

    using System;
    using System.Web;
    using NHibernate.Context;

    namespace NHibernate.Example.Web
    {
      public class CurrentSessionModule : IHttpModule
      {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(Application_BeginRequest);
            context.EndRequest += new EventHandler(Application_EndRequest);
        }

        public void Dispose()
        {
        }

        private void Application_BeginRequest(object sender, EventArgs e)
        {
            ManagedWebSessionContext.Bind(HttpContext.Current, ExampleApplication.SessionFactory.OpenSession());
        }

        private void Application_EndRequest(object sender, EventArgs e)
        {
            ISession session = ManagedWebSessionContext.Unbind(HttpContext.Current, ExampleApplication.SessionFactory);
      if(session !=null)
      {
            if (session.Transaction.IsActive)
            {
              session.Transaction.Rollback();
            }

            if (session != null)
            {
              session.Close();
            }
        }
        }
      }
    }
    ====================================================================
    另外我在Codesmith中也找到了一个关于session管理的模版,请看代码

    using System;
    using System.Collections.Generic;
    using System.Text;

    using NHibernate;
    using NHibernate.Cfg;

    namespace NHibernate.Generated.Base
    {
        public interface INHibernateSessionManager : IDisposable
        {
            // Methods
            INHibernateSession CreateSession();
      ISession CreateISession();

            // Properties
            INHibernateSession Session { get; }
        }

        /// <summary>
        /// A Singleton that creates and persits a single SessionFactory for the to program to access globally.
        /// This uses the .Net CallContext to store a session for each thread.
        ///
        /// This is heavely based on 'NHibernate Best Practices with ASP.NET' By Billy McCafferty.
        /// http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx
        /// </summary>
        public class NHibernateSessionManager : INHibernateSessionManager
        {
            #region Static Content

            private static INHibernateSessionManager _nHibernateSessionManager = null;
            /// <summary>
            /// Set method is exposed so that the INHibernateSessionManager can be swapped out for Unit Testing.
            /// NOTE: Cannot set Instance after it has been initialized, and calling Get will automatically intialize the Instance.
            /// </summary>
            public static INHibernateSessionManager Instance
            {
                get
                {
                    if(_nHibernateSessionManager == null)
                        _nHibernateSessionManager = new NHibernateSessionManager();
                    return _nHibernateSessionManager;
                }
                set
                {
                    if (_nHibernateSessionManager != null)
                        throw new Exception("Cannot set Instance after it has been initialized.");
                    _nHibernateSessionManager = value;
                }
            }

            #endregion

            #region Declarations

            private ISessionFactory _sessionFactory = null;
            private const string _sessionContextKey = "NHibernateSession-ContextKey";

            #endregion

            #region Constructors & Finalizers

            /// <summary>
            /// This will load the NHibernate settings from the App.config.
            /// Note: This can/should be expanded to support multiple databases.
            /// </summary>
            private NHibernateSessionManager()
            {
                _sessionFactory = new NHibernate.Cfg.Configuration().Configure().BuildSessionFactory();
            }
            ~NHibernateSessionManager()
            {
                Dispose(true);
            }

            #endregion

            #region IDisposable

            private bool _isDisposed = false;
            public void Dispose()
            {
                Dispose(false);
            }
            private void Dispose(bool finalizing)
            {
                if (!_isDisposed)
                {
                    // Close SessionFactory
                    _sessionFactory.Close();
                    _sessionFactory.Dispose();

                    // Flag as disposed.
                    _isDisposed = true;
                    if (!finalizing)
                        GC.SuppressFinalize(this);
                }
            }

            #endregion

            #region Methods

            public INHibernateSession CreateSession()
            {
                return new NHibernateSession(CreateISession());
            }
            public ISession CreateISession()
            {
                ISession iSession;
                lock (_sessionFactory)
                {
                    iSession = _sessionFactory.OpenSession();
                }
                return iSession;
            }

            #endregion

            #region Properties

            public INHibernateSession Session
            {
                get
                {
                    INHibernateSession session = ContextSession;

                    // If the thread does not yet have a session, create one.
                    if (session == null)
                    {
                        session = CreateSession();

                        // Save to CallContext.
                        ContextSession = session;
                    }

                    return session;
                }
            }
            private INHibernateSession ContextSession
            {
                get
                {
                    if (IsWebContext)
                        return (NHibernateSession)System.Web.HttpContext.Current.Items[_sessionContextKey];
                    else
                        return (NHibernateSession)System.Runtime.Remoting.Messaging.CallContext.GetData(_sessionContextKey);
                }
                set
                {
                    if (IsWebContext)
                        System.Web.HttpContext.Current.Items[_sessionContextKey] = value;
                    else
                        System.Runtime.Remoting.Messaging.CallContext.SetData(_sessionContextKey, value);
                }
            }
            private bool IsWebContext
            {
                get { return (System.Web.HttpContext.Current != null); }
            }

            #endregion
        }
    }


  • 相关阅读:
    Graphviz使用入门教程
    【编译原理笔记】抽象语法树AST图解
    cgo编译参数
    彻底解决Golang获取当前项目绝对路径问题
    udev和rules使用规则
    Linux系统启动U盘制作工具
    udev的rules定制和调试
    为什么变量名不能够以数字开头
    基于GCC的C语言抽象语法树重建与可视化研究
    Java7之后的intern
  • 原文地址:https://www.cnblogs.com/myssh/p/1500127.html
Copyright © 2020-2023  润新知