我认为好的学习Nhiberante的方法:
1了解HN的结构
2学习HN的项目,如:Cuyahoga
3看Hibernate的文档
4具体问题看NH的测试用例(我认为是最方便的方法,用例写的很全,也可以通过它学习NUnit),从这里也可以看到好的测试用例是最好的文档
下面是操作NH的通用类,来自Cuyahoga,有我的一些修改:
提供Session的类
using System;
using System.Reflection;

using NHibernate;
using NHibernate.Cfg;

namespace VirtualBank.Service


{

/**//// <summary>
/// The SessionFactory provides the NHibernate sessions and provides the possibility to register
/// additional classes with NHibernate by modules.
/// </summary>
public class SessionFactory

{
//是这个类
private static SessionFactory _sessionFactory = new SessionFactory();

private Configuration _nhibernateConfiguration;
//SessionFactory是Hibernate的概念,对应一个数据存储源
private ISessionFactory _nhibernateFactory;
private bool _classesAdded = false;


/**//// <summary>
/// Default constructor.
/// </summary>
protected SessionFactory()

{
RegisterCoreClasses();
}


/**//// <summary>
/// Gets the one instance of the SessionFactory. This is done with a singleton so we don't have
/// to register mappings etc. with every request.
/// </summary>
/// <returns></returns>
public static SessionFactory GetInstance()

{
return _sessionFactory;
}


/**//// <summary>
/// GetNHibernateFactory returns the current NHibernate ISessionFactory.
/// </summary>
public ISessionFactory GetNHibernateFactory()

{
return this._nhibernateFactory;
}


/**//// <summary>
/// Get a new NHibernate session.
/// </summary>
/// <returns></returns>
public ISession GetSession()

{
return this._nhibernateFactory.OpenSession();
}


/**//// <summary>
/// Add a class to the NHibernate mappings.
/// If the class already is mapped, nothing will happen.
/// </summary>
/// <param name="type"></param>
public void RegisterPersistentClass(Type type)

{
if (this._nhibernateConfiguration.GetClassMapping(type) == null)

{
// Class isn't mapped yet, so do it now.
this._nhibernateConfiguration.AddClass(type);
this._classesAdded = true;
}
}


/**//// <summary>
/// Rebuild the NHibernate ISessionFactory. Use it after registering new classes.
/// </summary>
public bool Rebuild()

{
// Rebuild NHibernate SessionFactory to activate the new mapping.
if (this._classesAdded)

{
this._nhibernateFactory = this._nhibernateConfiguration.BuildSessionFactory();
this._classesAdded = false;
return true;
}
else

{
return false;
}
}

private void RegisterCoreClasses()

{
Configuration config = new Configuration();
//??
this._nhibernateConfiguration = config.AddAssembly(this.GetType().Assembly);
//应用程序为了得到ISession实例,必须先得到它的工厂。这个工厂应该是被应用程序的所有线程共享的:

this._nhibernateFactory = this._nhibernateConfiguration.BuildSessionFactory();
}
}
}

具体操作的类,封装了一些通用方法
using System;
using System.Collections;
using System.Reflection;

using log4net;
using NHibernate;
using NHibernate.Expression;


namespace VirtualBank.Service


{

/**//// <summary>
/// This is the repository for persistance of the Cuyahoga core classes. Maybe it
/// should be split up into several classes, but we'll start with one
/// repository for all core classes.
/// </summary>
public class CoreRepository

{
private static readonly ILog log = LogManager.GetLogger(typeof(CoreRepository));

private ISessionFactory _factory;
private ISession _activeSession;


/**//// <summary>
/// Get the active NHibernate session.
/// </summary>
public ISession ActiveSession

{

get
{ return this._activeSession; }
}

/**//// <summary>
/// Create a repository for core objects.
/// </summary>
//TODO?语法
public CoreRepository() : this(false)

{
}


/**//// <summary>
/// Create a repository for core objects.
/// </summary>
/// <param name="openSession">Indicate if the CoreRepository should open a session and keep it in memory.</param>
public CoreRepository(bool openSession)

{
//看SessionFactory类
this._factory = SessionFactory.GetInstance().GetNHibernateFactory();
if (openSession)

{
this._activeSession = this._factory.OpenSession();
}
}


/**//// <summary>
/// Open a NHibernate session.
/// </summary>
public void OpenSession()

{
if (this._activeSession == null || ! this._activeSession.IsOpen)

{
this._activeSession = this._factory.OpenSession();
}
else

{
throw new InvalidOperationException("The repository already has an open session");
}
}


/**//// <summary>
/// Flushes the current active NHibernate session.
/// </summary>
public void FlushSession()

{
if (this._activeSession != null && this._activeSession.IsOpen)

{
this._activeSession.Flush();
}
}


/**//// <summary>
/// Close the active NHibernate session
/// </summary>
public void CloseSession()

{
if (this._activeSession != null)

{
if (this._activeSession.IsOpen)

{
this._activeSession.Close();
}
//this._activeSession.Dispose();
}
}

新的方法#region 新的方法
public object GetObjectById(Type type, Guid id)

{
if (this._activeSession != null)

{
return this._activeSession.Load(type,id);
}
else

{
throw new NullReferenceException("The repository doesn't have an active session");
}
}
public object GetObjectById(Type type, string id)

{
if (this._activeSession != null)

{
return this._activeSession.Load(type,id);
}
else

{
throw new NullReferenceException("The repository doesn't have an active session");
}
}


#endregion

Generic methods#region Generic methods


/**//// <summary>
/// Generic method for retrieving single objects by primary key.
/// </summary>
/// <param name="type">The type of the object to fetch.</param>
/// <param name="id">The identifier of the object.</param>
/// <returns></returns>
public object GetObjectById(Type type, int id)

{
if (this._activeSession != null)

{
return this._activeSession.Load(type, id);
}
else

{
throw new NullReferenceException("The repository doesn't have an active session");
}
}


/**//// <summary>
/// Generic method for retrieving single objects by primary key.
/// </summary>
/// <param name="type">The type of the object to fetch.</param>
/// <param name="id">The identifier of the object.</param>
/// <param name="allowNull">Allow null as return value.</param>
/// <returns></returns>
public object GetObjectById(Type type, int id, bool allowNull)

{
if (allowNull)

{
if (this._activeSession != null)

{
return this._activeSession.Get(type, id);
}
else

{
throw new NullReferenceException("The repository doesn't have an active session");
}
}
else

{
return GetObjectById(type, id);
}
}


/**//// <summary>
/// Get all objects of a given type.
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public IList GetAll(Type type)

{
return GetAll(type, null);
}


/**//// <summary>
/// Get all objects of a given type and add one or more names of properties to sort on.
/// </summary>
/// <param name="type"></param>
/// <param name="sortProperties"></param>
/// <remarks>Sorting is Ascending order. Construct a specific query/method when the sort order
/// should be different.</remarks>
/// <returns></returns>
public IList GetAll(Type type, params string[] sortProperties)

{
ICriteria crit = this._activeSession.CreateCriteria(type);
if (sortProperties != null)

{
foreach (string sortProperty in sortProperties)

{
crit.AddOrder(Order.Asc(sortProperty));
}
}
return crit.List();
}


/**//// <summary>
/// Generic method to insert an object.
/// </summary>
/// <param name="obj"></param>
public void SaveObject(object obj)

{
ITransaction trn = this._activeSession.BeginTransaction();
try

{
// Try to find a UpdateTimestamp property and when found, set it to the current date/time.
// PropertyInfo pi = obj.GetType().GetProperty("UpdateTimestamp");
// if (pi != null)
// {
// pi.SetValue(obj, DateTime.Now, null);
// }
this._activeSession.Save(obj);
trn.Commit();
}
catch (Exception ex)

{
trn.Rollback();
throw ex;
}
}


/**//// <summary>
/// Generic method to update an object.
/// </summary>
/// <param name="obj"></param>
public void UpdateObject(object obj)

{
ITransaction trn = this._activeSession.BeginTransaction();
try

{
this._activeSession.Update(obj);
trn.Commit();
}
catch (Exception ex)

{
trn.Rollback();
throw ex;
}
}


/**//// <summary>
/// Delete a specific object. Settings in the mapping file determine if this cascades
/// to related objects.
/// </summary>
/// <param name="obj"></param>
public void DeleteObject(object obj)

{
ITransaction trn = this._activeSession.BeginTransaction();
try

{
this._activeSession.Delete(obj);
trn.Commit();
}
catch (Exception ex)

{
trn.Rollback();
throw ex;
}
}


/**//// <summary>
/// Mark an object for deletion. Commit the deletion with Session.Flush.
/// </summary>
/// <param name="obj"></param>
public void MarkForDeletion(object obj)

{
this._activeSession.Delete(obj);
}


/**//// <summary>
/// Clear the cache for a given type.
/// </summary>
/// <param name="type"></param>
public void ClearCache(Type type)

{
log.Info("Clearing cache for type " + type.Name);
this._factory.Evict(type);
}


/**//// <summary>
/// Clear the cache for a given collection.
/// </summary>
/// <param name="roleName">The full path to a collection property,
/// for example Cuyahoga.Core.Domain.Node.Sections.</param>
public void ClearCollectionCache(string roleName)

{
log.Info("Clearing cache for collection property " + roleName);
this._factory.EvictCollection(roleName);
}


/**//// <summary>
/// Clear the cache for a given cacheRegion.
/// </summary>
/// <param name="cacheRegion"></param>
public void ClearQueryCache(string cacheRegion)

{
log.Info("Clearing query cache for cacheregion " + cacheRegion);
this._factory.EvictQueries(cacheRegion);
}

#endregion



}
}
