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. 011——数组(十一)array_merge array_merge_recursive array_change_key_case

    <?php /** */ //array_merge() 将多个数组合并,生成新数组.当键名相同时,后者覆盖前者 /*$array1=array('weburl'=>"bbs.b ...

  2. log4j打印不同颜色

    1.首先在eclipse中安装一个插件: ANSI COLOR 在Eclipse Marketplace 中直接搜索  ANSI COLOR 然后安装 2.在log4j 中加入红色字体部分: < ...

  3. mysql5.6与mysql5.5不同

    1.编译阶段 要明白with与without的区别,选项值分1和0,或者对应为on或off,代表支持与不支持:with的1(on)与without的0(off)是同样的,with的0(off)与wit ...

  4. 使用游标、存储过程、pivot 三种方法导入数据

    --使用游标循环 if (exists (select * from sys.objects where name = 'Base_RecordTend_Test')) drop proc Base_ ...

  5. Linux下MySQL小尝试

    因为我用的linux机器事先已经装好了mysql,所以安装部门就先忽略. 进入mysql,如果发现没权限的话,使用 mysql -uroot -p 输入密码即可 首先我们使用 create datab ...

  6. wget 认知及常用命令【转载】

    https://www.cnblogs.com/lxz88/p/6278268.html https://www.cnblogs.com/cindy-cindy/p/6847502.html

  7. 每周荐书:机器学习、Java虚拟机、微信开发(评论送书)

    每周荐书:机器学习.Java虚拟机.微信开发(评论送书) 感谢大家对每周荐书栏目的支持,先公布下上周中奖名单 年精心雕琢,难得的"理论 + 实战案例 + 趟坑经验"总结 从需求分析 ...

  8. 金三银四跳槽季,Java面试题大纲

    跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽.切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来(期间也没有准备充分),到底是因为技术原因(影响自己的发展,偏移自己规划的 ...

  9. matlab linux的安装(第二次)

    1 挂载 2 下载jdk,matlab里面那个不行,缺点东西 3 安装 ./install *** 4 激活,非在线 5 license.lic路径在百度云中有 6 运行路径在你安装过程中的选的路径, ...

  10. [Python]定时任务框架 APScheduler

    1.使用APScheduler教程 参考博客地址