关于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

你可能感兴趣的:(Hibernate)