- installare, se necessario, NH
- aggiungere il progetto Persistence alla solution
- aggiungere a Persistence il riferimento a NHibernate.dll e ai progetti della solution necessari (BusinessObjetcts, ...)
- aggiungere al file di configurazione del progetto che verrà avviato la sezione per NH:
<configSections>
<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<nhibernate>
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
<add key="hibernate.connection.connection_string" value="Server=localhost; Integrated Security=SSPI; Database=ComLog;" />
<add key="hibernate.default_schema" value="dbo" />
<!-- General -->
<add key="hibernate.use_proxy_validator" value="true"/>
<!-- SQL Generation -->
<add key="hibernate.max_fetch_depth" value="2"/>
<add key="hibernate.show_sql" value="false"/>
<add key="hibernate.connection.release_mode" value="on_close" />
<!-- Reflection Optimizer: null | lcg | codedom -->
<add key="hibernate.use_reflection_optimizer" value="true"/>
<add key="hibernate.bytecode.provider" value="lcg"/>
</nhibernate>
- aggiungere a Persistence la classe SessionHelper, che si occuperà di istanziare le sessioni dalla factory
Esempio:
using System.Reflection;
using NHibernate;
using NHibernate.Cfg;
namespace Persistence
{
public class SessionHelper
{
private static ISessionFactory factory;
static SessionHelper()
{
Configuration cfg = new Configuration();
cfg.AddAssembly(Assembly.GetExecutingAssembly());
factory = cfg.BuildSessionFactory();
}
public static ISession GetSession()
{
return factory.OpenSession();
}
public static ISession GetSession(IInterceptor interceptor)
{
return factory.OpenSession(interceptor);
}
- aggiungere i file di mapping di NH col nome classe.hbm.xml; esempio:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="BusinnessObjects"
namespace="BusinnessObjects">
<class name="Group" table="Groups" lazy="false">
<id name="Id">
<generator class="guid" />
</id>
<property name ="Name" />
</class>
</hibernate-mapping>
- ricordati di impostare i file di mapping come Embedded Resource
A questo punto è possibile usare la session per salvare/caricare oggetti:
ISession session = SessionHelper.GetSession();
using (session)
{
Group group = new Group();
group.Name = "gruppo test";
group.Id = new Guid();
session.SaveOrUpdate(group);
session.Flush();
}
Per migliorare l'architettura aggiungere provider e manager:
- aggiungere a Persistence la classe generica del ProviderNH; ad esempio:
using System;
using System.Collections.Generic;
using System.Reflection;
using NHibernate;
using NHibernate.Transform;
namespace Persistence
{
public class NHibernateProvider<T> : IDisposable
{
private ISession _session;
//public event EventHandler<BeforeCommitEventArgs> BeforeCommit;
protected ISession Session
{
get { return _session; }
set { _session = value; }
}
public NHibernateProvider()
{
Session = SessionHelper.GetSession();
}
public T LoadById(Int32 id)
{
return Session.Load<T>(id);
}
public T LoadById(String id)
{
return Session.Load<T>(id);
}
public IList<T> LoadAll()
{
return LoadAll(String.Empty, true);
}
public IList<T> LoadAll(String associationPath, Boolean lazy)
{
ICriteria criteria = Session.CreateCriteria(typeof(T));
if (lazy)
{
return criteria.List<T>();
}
else
{
return criteria.SetFetchMode(associationPath, FetchMode.Join)
.SetResultTransformer(new DistinctRootEntityResultTransformer()).List<T>();
}
}
public IList<T> LoadBy(String hql)
{
return Session.CreateQuery(hql).List<T>();
}
public void Save(T value)
{
ITransaction tx = Session.BeginTransaction();
Session.SaveOrUpdate(value);
//OnBeforeCommit(value);
try
{
tx.Commit(); // Fa commit e flush
}
catch (Exception ex)
{
tx.Rollback();
//Logger.Error(this, MethodInfo.GetCurrentMethod().Name, ex);
throw;
}
}
public void SaveNew(T value)
{
ITransaction tx = Session.BeginTransaction();
Session.Save(value);
//OnBeforeCommit(value);
try
{
tx.Commit(); // Fa commit e flush
}
catch (Exception ex)
{
tx.Rollback();
//Logger.Error(this, MethodInfo.GetCurrentMethod().Name, ex);
throw;
}
}
//private void OnBeforeCommit(T value)
//{
// if (BeforeCommit != null)
// BeforeCommit(this, new BeforeCommitEventArgs(value));
//}
public void Delete(T value)
{
Session.Delete(value);
Session.Flush();
}
public void Dispose()
{
Session.Close();
Session.Dispose();
}
}
}
- aggiungere i provider specifici per i vari business objects
- aggiungere i manager che utilizzano i provider specifici