关于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
关于NHibernate的一些代码的更多相关文章
- NHibernate 配置增加代码感知
Adding the Schema Include the schema in your Project, Solution, or Visual Studios XML Schemas folder ...
- NHibernate使用Access数据库的配置问题
NHibernate本身不支持Access数据库,一开始看网上各种文档,捣敲浪费了N分钟. 还是祭起Nuget神器引用NHibernate.JetDrive. 代码如下,搞定收工... private ...
- NHibernate的使用
本文档适合初级开发者或者是第一次接触NHibernate框架的朋友,其中NHibernate不是最新的版本,但是一个比较经典的版本 NHibernate 2.1.2,其中用红线标注的部分一定要仔细看, ...
- NHibernate变的简单
前言 这篇文章出自于我尝试学习使用Nhiberbnate的挫败感.我发现好像Nhibernate全部的介绍材料不是很模糊就是太详细.我所需要的就是一个简单直接的教程,能让我尽快对NHibernate熟 ...
- 华丽的NHibernate
华丽的NHibernate http://www.cnblogs.com/kissdodog/archive/2013/02/21/2919886.html 华丽的NHibernate NHibern ...
- C#——Nhibernate探索
C#—Nhibernate探索 本篇文章,让我们一起来探索Nhibernate. 首先我们去搜索Nhibernate下载地址,如下链接所示. 该版本可能是最新版,我下载的4.0.4.GA.其中GA意思 ...
- NHibernate 数据查询之Linq to NHibernate
刚学NHibernate的时候觉得,HQL挺好用的,但是终归没有与其他技术相关联,只有NHibernate用到,一来容易忘记,二来没有智能提示,排除错误什么的都不给力,直到看到一个同事用Linq to ...
- NHibernate 数据查询之Linto to NHibernate (第八篇)
NHibernate 数据查询之Linto to NHibernate (第八篇) 刚学NHibernate的时候觉得,HQL挺好用的,但是终归没有与其他技术 相关联,只有NHibernate用到,一 ...
- NHibernate使用之详细图解
本文档适合初级开发者或者是第一次接触NHibernate框架的朋友,其中NHibernate不是最新的版本,但是一个比较经典的版本 NHibernate 2.1.2,其中用红线标注的部分一定要仔细看, ...
随机推荐
- 011——数组(十一)array_merge array_merge_recursive array_change_key_case
<?php /** */ //array_merge() 将多个数组合并,生成新数组.当键名相同时,后者覆盖前者 /*$array1=array('weburl'=>"bbs.b ...
- log4j打印不同颜色
1.首先在eclipse中安装一个插件: ANSI COLOR 在Eclipse Marketplace 中直接搜索 ANSI COLOR 然后安装 2.在log4j 中加入红色字体部分: < ...
- mysql5.6与mysql5.5不同
1.编译阶段 要明白with与without的区别,选项值分1和0,或者对应为on或off,代表支持与不支持:with的1(on)与without的0(off)是同样的,with的0(off)与wit ...
- 使用游标、存储过程、pivot 三种方法导入数据
--使用游标循环 if (exists (select * from sys.objects where name = 'Base_RecordTend_Test')) drop proc Base_ ...
- Linux下MySQL小尝试
因为我用的linux机器事先已经装好了mysql,所以安装部门就先忽略. 进入mysql,如果发现没权限的话,使用 mysql -uroot -p 输入密码即可 首先我们使用 create datab ...
- wget 认知及常用命令【转载】
https://www.cnblogs.com/lxz88/p/6278268.html https://www.cnblogs.com/cindy-cindy/p/6847502.html
- 每周荐书:机器学习、Java虚拟机、微信开发(评论送书)
每周荐书:机器学习.Java虚拟机.微信开发(评论送书) 感谢大家对每周荐书栏目的支持,先公布下上周中奖名单 年精心雕琢,难得的"理论 + 实战案例 + 趟坑经验"总结 从需求分析 ...
- 金三银四跳槽季,Java面试题大纲
跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽.切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来(期间也没有准备充分),到底是因为技术原因(影响自己的发展,偏移自己规划的 ...
- matlab linux的安装(第二次)
1 挂载 2 下载jdk,matlab里面那个不行,缺点东西 3 安装 ./install *** 4 激活,非在线 5 license.lic路径在百度云中有 6 运行路径在你安装过程中的选的路径, ...
- [Python]定时任务框架 APScheduler
1.使用APScheduler教程 参考博客地址