NHibernate如何避免会话被关闭

时间:2015-10-18 10:17:46

标签: c# nhibernate fluent-nhibernate nhibernate-configuration

在我的班级中调用第二个查询时,我无法弄清楚为什么我的会话被关闭了。

首先我调用方法getPoliceData() 我运行得很好 之后我调用GetSkadeData() 并抛出错误:

DbFactory类看起来像这样

class DbFactory
{
    private static Lazy<ISessionFactory> factory = new Lazy<ISessionFactory>(GetSessionFactory, System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);

    public DbFactory()
    {



    }
    public List<PoliceData> getPoliceData()  {
    using (ISession session = OpenSession())
        {
            IList<PoliceData> pols = session.Query<PoliceData>().Where(p => p.policyNumber == 053126703).ToList();

         return pols.ToList();
        }

    }

    public List<SkadeData> getSkadeData()
    {
        using (ISession session = OpenSession())
        {
            IList<SkadeData> skader = session.Query<SkadeData>().Where(p => p.Postnr == "7700").ToList();

            return skader.ToList();
        }

    }



    private static ISession OpenSession()
    {
        return factory.Value.GetCurrentSession();
    }

    private static ISessionFactory GetSessionFactory()
    {
        //NHibernate.Cfg.Configuration
        var c = new Configuration();
        //c.Configure();
        c.DataBaseIntegration(db =>
        {
            db.ConnectionString = "Server=\"localhost\";database=testdb;Integrated Security=SSPI";
            db.Dialect<NHibernate.Dialect.MsSql2012Dialect>();

        });
        //c.Configure("c:\XML.xml");

        ModelMapper maps = new ModelMapper();
        maps.AddMapping<PoliceDataMap>();
        maps.AddMapping<SkadeDataMap>();
        c.AddMapping(maps.CompileMappingForAllExplicitlyAddedEntities());
        c.CurrentSessionContext<NHibernate.Context.ThreadLocalSessionContext>();
        //c.Configure().Configure();
        var sessionFac = c.BuildSessionFactory();
        return sessionFac;

        //return sessionFac.GetCurrentSession();

    }

}

当我从另一个类调用该方法时,我正在执行此操作

List<PoliceData> test = new List<PoliceData>();
List<SkadeData> skader = new List<SkadeData>();
DbFactory poli = new DbFactory();
test = poli.getPoliceData();
skader = poli.getSkadeData();

我是否需要创建dbfactory的新实例,或者是否可以为两个不同的查询使用相同的会话。 如果Nhibernate刚刚得到一次保证,之后你就可以在需要时打开和关闭会话。

2 个答案:

答案 0 :(得分:2)

通常(使用任何ORM工具)我们应该避免using(OpenSession()) {...}语句并保持会话打开,不仅是单个操作,而且是完整的Web请求或工作单元。检查文档:

2.3. Contextual Sessions

  

大多数使用NHibernate的应用程序需要某种形式的&#34; contextual&#34;会话,其中给定会话在给定上下文的范围内有效。但是,在不同的应用程序中,构成上下文的定义通常是不同的;并且不同的上下文将不同的范围定义为当前的概念。

     

...

     

有关其合同的详细讨论,请参阅NHibernate.Context.ICurrentSessionContext接口的API文档。它定义了一个方法CurrentSession(),实现负责跟踪当前的上下文会话。开箱即用,NHibernate附带了几个这个接口的实现:

     
      
  • NHibernate.Context.CallSessionContext - 当前会话由CallContext跟踪。您有责任绑定和取消绑定ISession   使用类CurrentSessionContext的静态方法的实例。

  •   
  • NHibernate.Context.ThreadStaticSessionContext - 当前会话存储在线程静态变量中。此上下文仅支持一个   会议工厂。您有责任绑定和取消绑定ISession   使用类CurrentSessionContext的静态方法的实例。

  •   
  • NHibernate.Context.WebSessionContext - 将当前会话存储在HttpContext中。您有责任绑定和取消绑定ISession   使用类CurrentSessionContext的静态方法的实例。

  •   
  • NHibernate.Context.WcfOperationSessionContext - 当前会话由WCF OperationContext跟踪。你需要注册   WCF中的WcfStateExtension扩展。你有责任绑定和   使用静态类方法取消绑定ISession实例   CurrentSessionContext。

  •   
  • NHibernate.Context.ManagedWebSessionContext - 当前会话由HttpContext跟踪。在NHibernate 4.0中删除 -   应该使用NHibernate.Context.WebSessionContext。你是   负责使用static绑定和取消绑定ISession实例   在这个类上的方法,它永远不会打开,刷新或关闭一个ISession   本身。

  •   

答案 1 :(得分:0)

您是否尝试使用factory.value.OpenSession()?

创建ISession

如果你想根据你的样本编码分享ISession,你可以修改你的方法以获取ISession然后你可以这样调用它:

DbFactory poli = new DbFactory();
using (ISession session = poli.OpenSession()) {
  test = poli.getPoliceData(session);
  skader = poli.getSkadeData(session);
}

现在你的方法变成了:

public List<SkadeData> getSkadeData(ISession session)
{
  IList<SkadeData> skader = session.Query<SkadeData>().Where(p => p.Postnr == "7700").ToList();

  return skader.ToList();
}

它可能有效!