zoukankan      html  css  js  c++  java
  • 关于NHibernate的一些代码

    SessionManager

    using System;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Web;
    using NHibernate;
    using NHibernate.Cfg;
    using NHibernate.Context;
     
    namespace Northwind.Repositories
    {
        /// <summary>
        /// A static (singleton) class to manage NHibernate.
        /// Manage NHibernate sessions using <see cref="Session"/>
        /// </summary>
        public sealed class SessionManager
        {
            private const string SESSIONKEY = "NHIBERNATE.SESSION";
            [ThreadStatic]
            private static ISession _Session; //this session is not used in web
            private readonly Configuration _configuration;
            private readonly ISessionFactory _sessionFactory;
     
            #region Constructor
     
            #region Singleton
            public static SessionManager Instance
            {
                get
                {
    //#if !INSTANCE
                    return Singleton.Instance;
    //#else
    //                return new SessionManager();
    //#endif
                }
            }
     
    //#if !INSTANCE
            private class Singleton
            {
                static Singleton() { }
                internal static readonly SessionManager Instance = new SessionManager();
            }
    //#endif
            #endregion
     
            /// <summary>
            /// Initializes a new instance of the <see cref="SessionManager"/> class.
            /// </summary>
            private SessionManager()
            {
                _configuration = RestoreConfiguration();
                if (_configuration == null)
                {
                    _configuration = new Configuration();
                    BuildConfiguration();
                }
                //get the session factory
                _sessionFactory = Configuration.BuildSessionFactory();
            }
     
            private void BuildConfiguration()
            {
                Configuration.Configure(); //configure from the app.config
     
                Configuration.AddAssembly(GetType().Assembly);//default- mapping is in this assembly
                //other examples:
                //Configuration.AddFile("file.hbm.xml"); //add files
                //Configuration.AddAssembly(assembly); //add assembly
                //Configuration.AddAssembly(assemblyName); //add assembly by name
                //foreach (string assemblyName in assemblyNames) //add enumerable of assemblies
                //    Configuration.AddAssembly(assemblyName);
    #if !DEBUG
                SaveConfiguration(Configuration);
    #endif
            }
            #endregion
     
            #region Configuration Serialization
            //specify a full path if required
            private const string _configurationFilePath = "Configuration.save";
            private static void SaveConfiguration(Configuration configuration)
            {
                IFormatter serializer = new BinaryFormatter();
     
                using (Stream stream = File.OpenWrite(_configurationFilePath))
                {
                    try
                    {
                        serializer.Serialize(stream, configuration);
                    }
                    catch (UnauthorizedAccessException)
                    {
                        Console.WriteLine("No write access to " + _configurationFilePath);
                    }
                }
            }
     
            /// <summary>
            /// Optimization- you could deploy the serialization file.
            /// </summary>
            private static Configuration RestoreConfiguration()
            {
    #if DEBUG
                return null;
    #endif
                if (!File.Exists(_configurationFilePath)) return null;
                IFormatter serializer = new BinaryFormatter();
     
                using (Stream stream = File.OpenRead(_configurationFilePath))
                {
                    return serializer.Deserialize(stream) as Configuration;
                }
            }
            #endregion
     
            #region NHibernate Setup
            /// <summary>
            /// Gets the <see cref="NHibernate.Cfg.Configuration"/>.
            /// </summary>
            internal Configuration Configuration { get { return _configuration; } }
     
            /// <summary>
            /// Gets the <see cref="NHibernate.ISessionFactory"/>
            /// </summary>
            internal ISessionFactory SessionFactory { get { return _sessionFactory; } }
     
            /// <summary>
            /// Closes the session factory.
            /// </summary>
            public void Close()
            {
                SessionFactory.Close();
            }
     
            internal static bool IsWeb { get { return (HttpContext.Current != null); } }
            #endregion
     
            #region NHibernate SessionContext (1.2+)
     
            /// <summary>
            /// Opens the conversation (if already existing, reuses it). Call this from Application_BeginPreRequestHandlerExecute
            /// </summary>
            /// <returns>A <see cref="NHibernate.ISession"/></returns>
            public ISession OpenConversation()
            {
                //you must set <property name="current_session_context_class">web</property> (or thread_static etc)
                ISession session = Session; //get the current session (or open one). We do this manually, not using SessionFactory.GetCurrentSession()
                //for session per conversation (otherwise remove)
                session.FlushMode = FlushMode.Never; //Only save on session.Flush() - because we need to commit on unbind in PauseConversation
                session.BeginTransaction(); //start a transaction
                CurrentSessionContext.Bind(session); //bind it
                return session;
            }
     
            /// <summary>
            /// Ends the conversation. If an exception occurs, rethrows it ensuring session is closed. Call this (or <see cref="PauseConversation"/> if session per conversation) from Application_PostRequestHandlerExecute
            /// </summary>
            public void EndConversation()
            {
                ISession session = CurrentSessionContext.Unbind(SessionFactory);
                if (session == null) return;
                try
                {
                    session.Flush();
                    session.Transaction.Commit();
                }
                catch (Exception)
                {
                    session.Transaction.Rollback();
                    throw;
                }
                finally
                {
                    session.Close();
                }
            }
     
            /// <summary>
            /// Pauses the conversation. Call this (or <see cref="EndConversation"/>) from Application_EndRequest
            /// </summary>
            public void PauseConversation()
            {
                ISession session = CurrentSessionContext.Unbind(SessionFactory);
                if (session == null) return;
                try
                {
                    session.Transaction.Commit(); //with flushMode=Never, this closes connections but doesn't flush
                }
                catch (Exception)
                {
                    session.Transaction.Rollback();
                    throw;
                }
                //we don't close the session, and it's still in Asp SessionState
            }
            #endregion
     
            #region NHibernate Sessions
     
            /// <summary>
            /// Explicitly open a session. If you have an open session, close it first.
            /// </summary>
            /// <returns>The <see cref="NHibernate.ISession"/></returns>
            public ISession OpenSession()
            {
                ISession session = SessionFactory.OpenSession();
                if (IsWeb)
                    HttpContext.Current.Items.Add(SESSIONKEY, session);
                else
                    _Session = session;
                return session;
            }
     
            /// <summary>
            /// Gets the current <see cref="NHibernate.ISession"/>. Although this is a singleton, this is specific to the thread/ asp session. If you want to handle multiple sessions, use <see cref="OpenSession"/> directly. If a session it not open, a new open session is created and returned.
            /// </summary>
            /// <value>The <see cref="NHibernate.ISession"/></value>
            public ISession Session
            {
                get
                {
                    //use threadStatic or asp session.
                    ISession session = IsWeb ? HttpContext.Current.Items[SESSIONKEY] as ISession : _Session;
                    //if using CurrentSessionContext, SessionFactory.GetCurrentSession() can be used
     
                    //if it's an open session, that's all
                    if (session != null && session.IsOpen)
                        return session;
     
                    //if not open, open a new session
                    return OpenSession();
                }
            }
            #endregion
     
        }
    }

    NHibernateModule:

    using System;
    using System.Web;
    using NHibernate;
    using NHibernate.Context;
    using Northwind;
     
    /// <summary>
    /// A simple HttpModule which loads NHibernate session
    /// </summary>
    public class NHibernateModule : IHttpModule
    {
        #region Implementation of IHttpModule
     
        /// <summary>
        /// Initializes a module and prepares it to handle requests.
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application 
        /// </param>
        public void Init(HttpApplication context)
        {
            context.BeginRequest += context_BeginRequest;
            context.EndRequest += context_EndRequest;
        }
     
        private static void context_BeginRequest(object sender, EventArgs e)
        {
            //use my session manager
            ISession session = SessionManager.Instance.OpenSession();
            CurrentSessionContext.Bind(session);
        }
     
        private static void context_EndRequest(object sender, EventArgs e)
        {
            ISessionFactory sessionFactory = SessionManager.Instance.SessionFactory;
            ISession session = CurrentSessionContext.Unbind(sessionFactory);
     
            if (session == null) return;
            if (session.Transaction != null)
            {
                if (session.Transaction.IsActive)
                {
                    //if there is an active session, commit it
                    session.Transaction.Commit();
                }
                else
                {
                    //
                    session.Transaction.Rollback();
                }
            }
     
            session.Close();
        }
     
        /// <summary>
        /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
        /// </summary>
        public void Dispose()
        {
        }
     
        #endregion
    }
    Web.config
    
    It needs to include these lines...
    
    <configuration>
       <!-- IIS 6 -->
        <system.web>
             <httpModules>
                <add name="NHibernateModule" type="NHibernateModule"/>
            </httpModules>
         </system.web>
         <!-- IIS 7 and Cassini. -->
        <system.webServer>
             <modules>
                <add name="NHibernateModule" type="NHibernateModule"/>
            </modules>
        </system.webServer>
    </configuration>
    NHibernate configuration
    
    The config file needs to include this line.
    
    <property name="current_session_context_class">
    web
    </property>
    

      GenericRepository:

    using System;
    using System.Collections.Generic;
    using NHibernate;
     
    namespace Northwind
    {
        /// <summary>
        /// A generic repository. Normally this would be a base class of customized entity repositories- not directly exposed.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <remarks>
        /// All operations are wrapped with <see cref="TransactionRequired"/>. If there is NO open transaction, they open a transaction and commit immediately. If there is an open transaction, nothing is commited, so you should commit at a higher level.
        /// </remarks>
        public class GenericRepository<T> where T : new()
        {
            protected ISession Session
            {
                get { return SessionManager.Instance.Session; }
            }
     
            #region Read
            /// <summary>
            /// Loads the specified id. Throws an exception if not in database.
            /// </summary>
            public T Load(object id)
            {
                using (TransactionRequired transaction = new TransactionRequired())
                {
                    return Session.Load<T>(id);
                }
            }
     
            /// <summary>
            /// Gets the Id. Returns null if there is no matching row
            /// </summary>
            public T GetById(object id)
            {
                using (TransactionRequired transaction = new TransactionRequired())
                {
                    return Session.Get<T>(id);
                }
            }
     
            /// <summary>
            /// Finds all records. Consider <see cref="FindPage"/> for large result sets.
            /// </summary>
            public ICollection<T> FindAll()
            {
                using (TransactionRequired transaction = new TransactionRequired())
                {
                    return Session.CreateCriteria(typeof(T)).List<T>();
                }
            }
     
            /// <summary>
            /// Counts the number of records.
            /// </summary>
            public int Count()
            {
                ICriteria criteria = Session.CreateCriteria(typeof(T));
                using (TransactionRequired transaction = new TransactionRequired())
                {
                    return criteria.SetProjection(NHibernate.Criterion.Projections.RowCount()).UniqueResult<int>();
                }
            }
     
            /// <summary>
            /// Finds records by page.
            /// </summary>
            /// <param name="pageStartRow">The page start row.</param>
            /// <param name="pageSize">Size of the page.</param>
            public IList<T> FindPage(int pageStartRow, int pageSize)
            {
                ICriteria criteria = Session.CreateCriteria(typeof(T));
                criteria.SetFirstResult(pageStartRow);
                criteria.SetMaxResults(pageSize);
                using (TransactionRequired transaction = new TransactionRequired())
                {
                    return criteria.List<T>();
                }
            }
     
            /// <summary>
            /// Finds records by page, sorted.
            /// </summary>
            public IList<T> FindSortedPage(int pageStartRow, int pageSize, string sortBy, bool descending)
            {
                ICriteria criteria = Session.CreateCriteria(typeof(T));
     
                if (descending)
                    criteria.AddOrder(NHibernate.Criterion.Order.Desc(sortBy));
                else
                    criteria.AddOrder(NHibernate.Criterion.Order.Asc(sortBy));
     
                criteria.SetFirstResult(pageStartRow);
                criteria.SetMaxResults(pageSize);
                using (TransactionRequired transaction = new TransactionRequired())
                {
                    return criteria.List<T>();
                }
            }
            #endregion
     
            #region Update
            /// <summary>
            /// Saves the specified object within a transaction.
            /// </summary>
            public void Save(T entity)
            {
                using (TransactionRequired transaction = new TransactionRequired())
                {
                    Session.Save(entity);
                    transaction.Commit(); //flush to database
                }
            }
     
            /// <summary>
            /// Saves the specified object within a transaction.
            /// </summary>
            public void SaveOrUpdate(T entity)
            {
                using (TransactionRequired transaction = new TransactionRequired())
                {
                    Session.SaveOrUpdate(entity);
                    transaction.Commit(); //flush to database
                }
            }
     
            /// <summary>
            /// Deletes the specified object within a transaction.
            /// </summary>
            public void Delete(T entity)
            {
                using (TransactionRequired transaction = new TransactionRequired())
                {
                    Session.Delete(entity);
                    transaction.Commit(); //flush to database
                }
            }
            #endregion
        }
    }

    TransactionRequired:

    using System;
    using NHibernate;
     
    namespace Northwind.Repositories
    {
        /// <summary>
        /// Ensure a code block is transactional.
        /// If the session transaction is not open, create a transaction; otherwise there is an existing transaction so don't do anything.
        /// </summary>
        /// <remarks>
        /// Equivalent to <see cref="System.Transactions.TransactionScope"/> with default <see cref="System.Transactions.TransactionScopeOption"/> value <c>Required</c> (enlist in enclosing transaction or create a new one if it doesn't exist).
        /// </remarks>
        public sealed class TransactionRequired : IDisposable
        {
            private const string TRANSACTIONKEY = "NHIBERNATE.TRANSACTION";
            private ITransaction _transaction;
            private bool _shouldCommit;
            private bool _completed;
     
            #region Constructor
            public TransactionRequired(ISession session)
            {
                if (session == null) throw new ArgumentNullException("session");
                _transaction = session.Transaction; //equal to Transaction.Current
                if (!IsOpenTransaction(_transaction))
                {
                    _transaction = session.BeginTransaction();
                    ShouldCommit = true;
                }
            }
            #endregion
     
            #region NHibernate Transactions
     
            /// <summary>
            /// Gets or sets a value indicating whether this transaction should commit. If there is an open transaction, by default calling Commit will not do anything- it will leave the transaction open.
            /// </summary>
            /// <value><c>true</c> if should commit; otherwise, <c>false</c>.</value>
            public bool ShouldCommit
            {
                get { return _shouldCommit; }
                set { _shouldCommit = value; }
            }
     
            public void Commit()
            {
                if (!ShouldCommit) return;
     
                if (_completed)
                    throw new InvalidOperationException("The current transaction is already committed. You should dispose the transaction.");
     
                _completed = true;
     
                try
                {
                    if (IsOpenTransaction(_transaction))
                    {
                        _transaction.Commit();
                        _transaction = null;
                    }
                }
                catch (HibernateException)
                {
                    RollbackTransaction();
                    throw;
                }
            }
     
            public void RollbackTransaction()
            {
                if (!ShouldCommit) return;
                _completed = true;
     
                if (IsOpenTransaction(_transaction))
                    _transaction.Rollback();
                _transaction = null;
            }
     
            private static bool IsOpenTransaction(ITransaction transaction)
            {
                return transaction != null && !transaction.WasCommitted && !transaction.WasRolledBack;
            }
     
            #endregion
     
     
            #region IDisposable Members
     
            public void Dispose()
            {
                if (!ShouldCommit) return;
                RollbackTransaction();
            }
     
            #endregion
        }
    }

    原文出处:http://www.martinwilley.com/net/code/nhibernate/index.html

  • 相关阅读:
    Go 模板
    使用Go开发web服务器
    CLI:使用Go开发命令行应用
    MyBatis 注解使用动态SQL
    Tomcat 使用Redis存储Session
    [翻译] java NIO Buffer
    [翻译] java NIO Channel
    [翻译]java nio 概述
    [翻译] java NIO 教程---介绍
    接口的定义常量与使用
  • 原文地址:https://www.cnblogs.com/flykai/p/3244184.html
Copyright © 2011-2022 走看看