开发者

What is a good way to setup CRUD methods and SessionFactory in Nhibernate?

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜