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

关于NHibernate的一些代码的更多相关文章

  1. NHibernate 配置增加代码感知

    Adding the Schema Include the schema in your Project, Solution, or Visual Studios XML Schemas folder ...

  2. NHibernate使用Access数据库的配置问题

    NHibernate本身不支持Access数据库,一开始看网上各种文档,捣敲浪费了N分钟. 还是祭起Nuget神器引用NHibernate.JetDrive. 代码如下,搞定收工... private ...

  3. NHibernate的使用

    本文档适合初级开发者或者是第一次接触NHibernate框架的朋友,其中NHibernate不是最新的版本,但是一个比较经典的版本 NHibernate 2.1.2,其中用红线标注的部分一定要仔细看, ...

  4. NHibernate变的简单

    前言 这篇文章出自于我尝试学习使用Nhiberbnate的挫败感.我发现好像Nhibernate全部的介绍材料不是很模糊就是太详细.我所需要的就是一个简单直接的教程,能让我尽快对NHibernate熟 ...

  5. 华丽的NHibernate

    华丽的NHibernate http://www.cnblogs.com/kissdodog/archive/2013/02/21/2919886.html 华丽的NHibernate NHibern ...

  6. C#——Nhibernate探索

    C#—Nhibernate探索 本篇文章,让我们一起来探索Nhibernate. 首先我们去搜索Nhibernate下载地址,如下链接所示. 该版本可能是最新版,我下载的4.0.4.GA.其中GA意思 ...

  7. NHibernate 数据查询之Linq to NHibernate

    刚学NHibernate的时候觉得,HQL挺好用的,但是终归没有与其他技术相关联,只有NHibernate用到,一来容易忘记,二来没有智能提示,排除错误什么的都不给力,直到看到一个同事用Linq to ...

  8. NHibernate 数据查询之Linto to NHibernate (第八篇)

    NHibernate 数据查询之Linto to NHibernate (第八篇) 刚学NHibernate的时候觉得,HQL挺好用的,但是终归没有与其他技术 相关联,只有NHibernate用到,一 ...

  9. NHibernate使用之详细图解

    本文档适合初级开发者或者是第一次接触NHibernate框架的朋友,其中NHibernate不是最新的版本,但是一个比较经典的版本 NHibernate 2.1.2,其中用红线标注的部分一定要仔细看, ...

随机推荐

  1. FreeMarker初探--安装FreeMarker

    这里安装FreeMarker相当简单,不需要真正的安装过程.仅仅是拷贝 lib/freemarker.jar 到你 Java 应用程序的路径中,让类加载器可以发现它.比如,如果你在 Web 使用了 F ...

  2. Algorithm1: 全排列

    全排列 思想:      这是一个全排列问题,需要使用递归实现,将数组中的所有元素和第一个元素交换,求后面n-1个元素的全排列.      按照这个条件递归下去,知道元素的个数只有一个的时候,输出所有 ...

  3. SpringXML方式给bean初始化属性值

    可以在Spring容器初始化bean的时候给bean的属性赋初始值,直接在property标签里设置即可 1 2 3 4 5 6 <bean name="user**" cl ...

  4. yii2 实现excel导出功能

    官方教程地址:http://www.yiiframework.com/extension/yii2-export2excel/ 安装: Either run php composer.phar req ...

  5. C++面向对象高级编程(二)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 知识点1.重载成员函数 知识点2 . return by value, return by reference 知识点3 重载非成员函数 ...

  6. 【dlbook】正则化

    对学习算法的修改——旨在减少泛化误差而不是训练误差 显著减少方差而不过度增加偏差. [参数范数惩罚] 通常只对权重做惩罚而不对偏置做惩罚,原因是拟合偏置比拟合权重容易很多. 不同层使用不同惩罚的代价很 ...

  7. modprobe lsmod

    modprobe是linux的一个命令,可载入指定的个别模块,或是载入一组相依的模块.modprobe会根据depmod所产生的相依关系,决定要载入哪些模块.若在载入过程中发生错误,在modprobe ...

  8. Linux 用C语言实现简单的shell(2)

    不知不觉两周没有发文了,因为“一万美金的福特奖学金答辩”,ACM比赛,网络论文阅读和网络大作业一大堆事把时间冲散了,所以先写一篇博文补上之前一坑. 之前发了一篇关于linux 用C语言实现简单shel ...

  9. XMLHttpRequest cannot load file浏览器无法异步加载本地file文件

    原因:Chrome不支持本地Ajax请求,在.html文件中访问.json文件时就会出现这个问题,就是说这个时候不能加载这个.html文件. 解决方式 打开Chrome快捷方式的属性中设置: 右击Ch ...

  10. lydsy个人代码.zip

    /s/12vaj9vUNLMlEPxlhw4xRwA ryap 感谢@yirannn 省选前++rp