ASP.NET NHibernate - 没有懒惰地初始化集合没有会话或会话被关闭

时间:2016-01-26 02:18:27

标签: c# asp.net nhibernate lazy-loading

我在ASP.NET WebForms Application上遇到了NHibernate的一些问题。

我可以做任何事情 - 保存,获取,删除,更新注册,但是当我尝试使用延迟集合获取某些对象时,异常会引发:

  

会话已关闭

我已经尝试了一切。有人可以帮忙吗?

RepositoryClass

    private ISession m_session = NHibernateHelper.OpenSession();

    protected ISession Session
    {
        get
        {
            return m_session;
        }
    }

    public virtual void Update(T entity)
    {
        using (ITransaction transaction = Session.BeginTransaction())
        {
            Session.Merge(entity);
            transaction.Commit();
        }
    }

    public virtual int Count()
    {
        return (from t in Session.Query<T>()
                select t).Count();
    }

    public virtual void Remove(T entity)
    {
        using (ISession session = NHibernateHelper.OpenSession())
            try
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Delete(entity);
                    transaction.Commit();
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
    }

    public virtual void Remove(int id)
    {
        using (ISession session = NHibernateHelper.OpenSession())
            try
            {
                T entity = session.Get<T>(id);
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Delete(entity);
                    transaction.Commit();
                }
            }
            catch (Exception e)
            {

                throw new Exception(e.Message);


            }
    }

    public virtual IList<T> ListAll()
    {
        return (from t in Session.Query<T>()
                select t).ToList();
    }

    public virtual T Get(Type entityType, object id)
    {
        return (T)Session.Get(entityType, id);
    }

    public virtual T Get(object id)
    {
        return Session.Get<T>(id);
    }

    public virtual void Save(T entity)
    {
        using (ISession session = NHibernateHelper.OpenSession())
        using (ITransaction transaction = session.BeginTransaction())
        {
            session.Save(entity);
            transaction.Commit();
        }
    }

NHibernateHelper

public class NHibernateHelper
{
    private static ISessionFactory _sessionFactory = null;

    private static ISessionFactory GetSessionFactory()
    {
        return CreateSessionFactory();
    }

    private static Object createLock = new Object();

    private static ISessionFactory CreateSessionFactory()
    {
        lock (createLock)
        {

            if (_sessionFactory == null)
            {

                Configuration config = new Configuration().Configure(System.Reflection.Assembly.GetExecutingAssembly(), "Repositorio.hibernate.cfg.xml");
                _sessionFactory = config.BuildSessionFactory();
            }


            return _sessionFactory;
        }
    }

    public static ISession OpenSession()
    {
        return GetSessionFactory().OpenSession();
    }
}

1 个答案:

答案 0 :(得分:1)

我没有把我的会话管理放在我的回购中。可能发生的是您从repo打开会话的项目列表,然后将对象传递回控制器(页面/视图或者您设计它)。但是当控制器获取项目时,您已完成了repo的工作,并且已关闭会话。 在您的控制器中,您点击了懒惰属性,但由于会话已关闭,您将获得延迟异常。 要使延迟属性可用,您需要将对象附加到实时会话,直到完成工作单元。因此,你可以在将它们交给控制器之前点击repo中的惰性属性(这种方式会使懒惰的目的失效),或者你可以将会话控制放在链的上方。

我的http请求负责会话,并使用RequestHttpModule在生命周期内为每个请求创建一个活动会话(无论我是否需要)。这样,当视图控制器命中惰性属性时,该对象仍然附加到实时会话以获取惰性对象。 你可以'Bing'为'每个请求的nhibernate会话',你会发现一些博客详细说明模式。

我的请求模块如下:

public class RequestHttpModule : IHttpModule {
        public void Init(HttpApplication context) {
            context.BeginRequest += new EventHandler(ContextBeginRequest);
            context.EndRequest += new EventHandler(ContextEndRequest);
        }

        public void Dispose() { }

        public void ContextBeginRequest(Object sender, EventArgs e) {
            SessionManager.GetInstance().OpenSession();
        }

        public void ContextEndRequest(Object sender, EventArgs e) {
            SessionManager.GetInstance().DisposeCurrentSession();
        }
}

然后在Web.config中注册模块

<system.webServer>
    <modules>
      <add name="RequestHttpModule" type="MyWebApp.RequestHttpModule" />
    </modules>
  </system.webServer>

}