asp.net Управление сессиями Nhibernate - PullRequest
0 голосов
/ 26 декабря 2011

Я реализую стандартный сценарий в сеансе asp.net на запрос. Мой модуль asp.net:

public class NHibernateSessionModule : IHttpModule
{
    public void Dispose() { }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += context_BeginRequest;
        context.EndRequest += context_EndRequest;
    }

    void context_BeginRequest(object sender, EventArgs e)
    {
        var session = SessionManager.SessionFactory.OpenSession();
        session.BeginTransaction();
        CurrentSessionContext.Bind(session);

    }

    void context_EndRequest(object sender, EventArgs e)
    {
        var session = SessionManager.CurrentSession;
        if (session != null)
        {
            try
            {
                if (session.Transaction != null && session.Transaction.IsActive)
                    session.Transaction.Commit();
            }
            catch (Exception ex)
            {
                session.Transaction.Rollback();
                throw new ApplicationException("Error committing database transaction", ex);
            }
            finally
            {
                session.Close();
            }
        }
        CurrentSessionContext.Unbind(SessionManager.SessionFactory);
    }
}

Мой sessionManager является поточно-ориентированным синглетом:

public class SessionManager
{
    private readonly ISessionFactory sessionFactory;
    public static ISessionFactory SessionFactory
    {
        get { return Instance.sessionFactory; }
    }
    private ISessionFactory GetSessionFactory()
    {
        return sessionFactory;
    }
    public static ISession OpenSession()
    {
        return Instance.GetSessionFactory().OpenSession();
    }
    public static ISession CurrentSession
    {
        get
        {
            if (!CurrentSessionContext.HasBind(Instance.GetSessionFactory()))
                return null;
            return Instance.GetSessionFactory().GetCurrentSession();
        }
    }


    public static SessionManager Instance
    {
        get
        {
            return NestedSessionManager.sessionManager;
        }
    }
    private SessionManager()
    {
        Configuration configuration = new Configuration().Configure();
        sessionFactory = configuration.BuildSessionFactory();
    }

    class NestedSessionManager
    {
        internal static readonly SessionManager sessionManager =
            new SessionManager();
    }
}

Основная идея - открыть сеанс в начале запроса, а затем использовать сеанс через SessionManager.CurrentSession;

Сессия хранится в настроенном контексте:

<property name="current_session_context_class">web</property>

Мой репозиторий:

public class RepositoryNew<T> : BaseRepository<T>, IDisposable
{
    public RepositoryNew()
    {
        if (NHibernateSession == null)
            //Start session for not web version
    }
    public void Dispose()
    {
        //flush session for not web version
    }

    protected override sealed ISession NHibernateSession
    {
        get
        {
            return SessionManager.CurrentSession; 
        }
    }
}

Использование

protected void Page_Load(object sender, EventArgs e)
{          
    var repo = new RepositoryNew<Client>()
    clients = repo.GetAll();
}

По какой-то причине этот репозиторий не использует открытый сеанс в модуле.

CurrentSessionContext.HasBind(Instance.GetSessionFactory())

возвращает false, поэтому мой код запускает второй сеанс в запросе. В отладчике я вижу, что я дважды создал экземпляр SessionManager. У меня есть две разные фабрики ISesssion. У меня пока нет идей, что не так. Я потратил на это много часов.

Ответы [ 2 ]

0 голосов
/ 26 декабря 2011

Это была странная ошибка. Когда я удаляю ссылку на SessionManager из моего проекта, он начинает работать правильно.

0 голосов
/ 26 декабря 2011

Может быть, еще одна вещь откроет сеанс в Http Begin Request, потому что каждый http-запрос будет открывать новый сеанс, такой как запрос статического изображения, вы должны изменить эту стратегию, чтобы исключить этот ненужный сеанс в каждом Http-запросе, который вы можете прочитать в этом блоге, и изменить свою стратегию http://nhforge.org/blogs/nhibernate/archive/2011/03/03/effective-nhibernate-session-management-for-web-apps.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...