3

我无法弄清楚为什么我在课堂上调用第二个查询时关闭了会话。

首先我调用方法 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 只配置一次,然后您只需在需要时打开和关闭会话,那就太好了。

4

2 回答 2

3

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

2.3. 上下文会话

大多数使用 NHibernate 的应用程序都需要某种形式的“上下文”会话,其中给定的会话在给定上下文的整个范围内都有效。然而,在不同的应用程序中,构成上下文的定义通常是不同的。不同的上下文为当前的概念定义了不同的范围。

...

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

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

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

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

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

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

于 2015-10-18T10:27:19.557 回答
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();
}

它可能会起作用!

于 2015-10-18T14:35:30.477 回答