I'm using NHibernate + Fluent to handle the database in my application. So far I've been using a SessionSource to create my ISession objects. I'm a bit confused now about what comes from NHibernate or Fluent, and what I really should use for creating my sessions.
ISession comes from NHibernate, and the SessionSource from Fluent. I create the SessionSource from a FluentConfiguration, and currently use the SessionSource to create sessions. This is my function to create sessions. The FluentConfiguration and SessionSource is reused:
if (_sessionSource == null)
{
_cfg = Fluently.Configure().Database(SQLiteConfiguration.Standard.ShowSql().UsingFile("test.db"));
_sessionSource = new SessionSource(_cfg.BuildConfiguration().Properties, new MappingsPersistenceModel());
var session = _sessionSource.CreateSession();
_sessionSource.BuildSchema(session);
return session;
}
return _sessionSource.CreateSession();
Does this look reasonable? It sounds more appealing to use a ISessionFactory to create sessions though,开发者_开发知识库 so I tried using one. This comes from NHibernate, so I don't know if that's why it is a problem, but it fails when my sessions are created from an ISessionFactory.
// Done once:
_sessionFactory = _cfg.BuildSessionFactory();
// Done each time a session is requested:
_sessionFactory.OpenSession()
Using this I get a MappingException
when using the session, saying "No persister for: MyProject.Model.SomeModelClass".
Should I keep using the SessionSource? Or am I missing something regarding the ISessionFactory?
The problem seems to be that the SessionFactory doesn't know about the mappings since they are only given to the SessionSource. Adding the mappings during the fluent configuration and getting the factory from this seems to help. This gave me what looks like a better solution. Does this look reasonable to those of you with more experience on this?
private static ISession CreateSession()
{
if (_sessionFactory == null)
{
_sessionFactory = Fluently.Configure().
Database(SQLiteConfiguration.Standard.ShowSql().UsingFile("test.db")).
Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingsPersistenceModel>()).
BuildSessionFactory();
}
return _sessionFactory.OpenSession();
}
Please see this class may be help full for you.I have write methods for create factory and session.
public class Common
{
public const string NHibernateSessionKey = "nhibernate.session.key";
public static string ConnString
{
get
{
return System.Configuration.ConfigurationManager.ConnectionStrings["JewelSoftMySqlConn"].ConnectionString;
}
}
public static ISessionFactory FACTORY = CreateFactory();
static ISessionFactory CreateFactory()
{
Configuration config = new Configuration();
IDictionary props = new Hashtable();
props.Add("hibernate.dialect", "NHibernate.Dialect.MySQLDialect");
props.Add("hibernate.connection.provider", "NHibernate.Connection.DriverConnectionProvider");
props.Add("hibernate.connection.driver_class", "NHibernate.Driver.MySqlDataDriver");
props.Add("hibernate.connection.connection_string", Common.ConnString);
config.AddProperties(props);
config.AddInputStream(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(Resource.Models_hbm)));
return config.BuildSessionFactory();
}
public static ISession GetCurrentSession()
{
ISession currentSession = null;
HttpContext context = HttpContext.Current;
if (context != null)
{
currentSession = context.Items[NHibernateSessionKey] as ISession;
if (currentSession == null)
{
currentSession = FACTORY.OpenSession();
context.Items[NHibernateSessionKey] = currentSession;
}
}
else//will work non web request, like in test environment
currentSession = FACTORY.OpenSession();
return currentSession;
}
}
I know how you feel! The divide between fluent and NH can be rather confusing at the start. In my opinion you should not use SessionSource, AFAIK it is only really useful in testing scenarios. I recomend that you just use the ISessionFactory directly from NH.
Can you post your error? You seem to be using it correctly, so probably there is something wrong with the configuration or the cfg object.
精彩评论