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. java根据所给的根目录获取底下所有文件夹结构

    所写工具类背景:项目经理叫我写个工具类实现:给个项目的根目录分析java文件及jsp文件.记录文件类型.路径.文件名和包名. 定义的实体类(这里我用了easypoi以后方便写入excel文档) @Da ...

  2. 微信授权网页获取用户openiid

    微信网页授权:官方文档: https://mp.weixin.qq.com/wiki 支付文档:https://pay.weixin.qq.com/wiki/doc/api/index.html 调试 ...

  3. vue 初级小总结

    (1)插值,即渲染文本 文本:数据绑定最常见的形式就是使用 {{...}}(双大括号)的文本插值 <h1>{{ message }}</h1> data() { return ...

  4. Java多线程编程实战指南(核心篇)读书笔记(五)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  5. Unity 异步网络方案 IOCP Socket + ThreadSafe Queue

    Unity IOCP Socket + ThreadSafe Queue 1.Socket.BeginReceive系列接口在unityweb下是不正常的,页面刷新会导致问题 2.自己维护线程,会带来 ...

  6. 从零开始编写深度学习库(五)PoolingLayer 网络层CPU编写

    记录:编写卷积层和池化层,比较需要注意的细节就是边界问题,还有另外一个就是重叠池化的情况,这两个小细节比较重要,边界问题pad在反向求导的时候,由于tensorflow是没有计算的,另外一个比较烦人的 ...

  7. day3 文件系统 内核模块 ctags

    nfs网络文件系统 smb   修改配置文件  sudo  vim /etc/samba/smb.conf    重启服务   /etc/init.d/samba restart 自制小的文件系统 1 ...

  8. 使用Percona Xtrabackup创建MySQL slave库

    一.使用Percona Xtrabackup创建MySQL slave库 MySQL Server 版本: Server version: 5.7.10-log MySQL Community Ser ...

  9. LOJ2500 NOIP2014 飞扬的小鸟 【背包DP】*

    LOJ2500 NOIP2014 飞扬的小鸟 LINK 题目大意就是说有n个柱子,在每一秒你可以选择不点下降高度y和点p次上升x∗p,若果当前位置加上x∗p大于上界m,就会停在m. 如果可以成功穿越所 ...

  10. JavaWeb向浏览器返回一个音频流

    浏览器直接播放音频文件,1是直接访问一个html的音频文件,,2 是返回一个Java音频流给浏览器解析. 下面实现一个java的wav文件音频流,可以直接播放音频文件 package org.lib. ...