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

  • 相关阅读:
    Leetcode 811. Subdomain Visit Count
    Leetcode 70. Climbing Stairs
    Leetcode 509. Fibonacci Number
    Leetcode 771. Jewels and Stones
    Leetcode 217. Contains Duplicate
    MYSQL安装第三步报错
    .net 开发WEB程序
    JDK版本问题
    打开ECLIPSE 报failed to load the jni shared library
    ANSI_NULLS SQL语句
  • 原文地址:https://www.cnblogs.com/flykai/p/3244184.html
Copyright © 2011-2022 走看看