3

現在、セッションファクトリを作成するNHibernateHelperクラスがあります。「SessionClosed!」というエラーが表示され続けます。私はこれについて間違った方法で行っていますか?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
   }

コストがかかるのはファクトリの作成であるため、ヘルパーを使用するのは良いことです。セッションを開くのは安価な操作なので、このような共有セッションを持つ必要はありません。

ファクトリ ヘルパーをスレッドセーフにする方法を示す別の SO の質問へのリンクを次に示します。

NHibernate SessionFactory が 1 回だけ作成されるようにする

于 2010-08-24T08:43:02.697 に答える