I currently have a NHibernateHelper class which creates a session factory. I keep recieving errors saying 'Session Closed!'. Am I going about this in the wrong way? The error occurs when I call the Add(Login login) which gets called after Add(User user)
public class NHibernateHelper
{
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
var configuration = new Configuration();
configuration.Configure();
configuration.AddAssembly("System.Core");
_sessionFactory = configuration.BuildSessionFactory();
}
return _sessionFactory;
}
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
Here is my repository:
internal class UserRepository : IUserRepository
{
private ISession _db = NHibernateHelper.OpenSession();
public void Add(User user)
{
using (_db)
{
using (ITransaction transaction = _db.BeginTransaction())
{
IEnumerable<UserRole> userRoles = user.UserRoles;
user.UserRoles = null;
_开发者_如何转开发db.Save(user);
foreach (UserRole userRole in userRoles)
{
userRole.UserID = user.UserID;
_db.Save(userRole);
}
transaction.Commit();
}
}
}
public void Add(Login login)
{
using (_db)
{
using (ITransaction transaction = _db.BeginTransaction())
{
_db.Save(login);
transaction.Commit();
}
}
}
}
This is because you are calling using(_db), which closes the session at the end of the block.
Rather than having the variable _db just call OpenSession for each operation
public void Add(User user)
{
using (ISession session = NHibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
IEnumerable<UserRole> userRoles = user.UserRoles;
user.UserRoles = null;
session.Save(user);
foreach (UserRole userRole in userRoles)
{
userRole.UserID = user.UserID;
session.Save(userRole);
}
transaction.Commit();
}
}
}
UPDATE:
public void Add(Login login)
{
using (ISession session = NHibernateHelper.OpenSession())
{
Add(login, session);
}
}
public void Add(Login login, ISession session)
{
//no longer need to create a session here - it is passed in
//using (ISession session = NHibernateHelper.OpenSession())
...Add using the session
}
It is the creation of the factory that is expensive, so your Helper is a good thing to use. Opening the session is a cheap operation, so no need to have a shared session like this.
Here is a link to another SO question that shows how to make your factory helper threadsafe:
Ensure NHibernate SessionFactory is only created once
精彩评论