Как правильно настроить методы CRUD и SessionFactory в Nhibernate? - PullRequest
3 голосов
/ 24 августа 2010

В настоящее время у меня есть класс NHibernateHelper, который создает фабрику сеансов.Я продолжаю получать сообщения об ошибках: «Сессия закрыта!».Я поступаю об этом неправильно?Ошибка возникает, когда я вызываю Add (логин), который вызывается после Add (пользователь)

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

        }
}

1 Ответ

2 голосов
/ 24 августа 2010

Это потому, что вы звоните с помощью (_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();
            }

        }
    }

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
   }

Это создание фабрики, которая стоит дорого, поэтому ваш Помощник - хорошая вещь для использования. Открытие сеанса - дешевая операция, поэтому не нужно иметь общий сеанс, подобный этому.

Вот ссылка на другой SO вопрос, который показывает, как сделать ваш фабричный вспомогательный поток безопасным:

Убедитесь, что NHibernate SessionFactory создается только один раз

...