3

我目前有一个创建会话工厂的 NHibernateHelper 类。我不断收到错误提示“会话已关闭!”。我会以错误的方式解决这个问题吗?当我调用在 Add(User user) 之后调用的 Add(Login login) 时发生错误

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();
    }
}

这是我的存储库:

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();
                }
            }

        }
}
4

1 回答 1

2

这是因为您正在调用 using(_db),它会在块结束时关闭会话。

而不是让变量 _db 只是为每个操作调用 OpenSession

    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();
            }

        }
    }

更新:

   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
   }

昂贵的是工厂的创建,所以你的 Helper 是一个好用的东西。打开会话是一个便宜的操作,所以不需要像这样的共享会话。

这是另一个 SO 问题的链接,该问题显示了如何使您的工厂助手线程安全:

确保 NHibernate SessionFactory 只创建一次

于 2010-08-24T08:43:02.697 回答