使用相同的id调用NHibernate ISession.get <t>(对象id)两次返回两个不同的实例

时间:2016-09-15 12:03:44

标签: c# sqlite nhibernate

这是我的理解 - 例如来自First and Second Level caching in NHibernate之类的来源 - 当使用“默认”设置 - 会话等时,NHibernate的ISession.get<T>(object id)应该返回相同的实例,如果使用相同的id调用两次。但是,我有两个不同的实例。

我看到过类似的问题,但thisthis等搜索没有有用的结果。

这是我的get方法:

BillingItem IEntityRepository.GetBillingItemByID(int id)
{
    var session = Helpers.NHibernateHelper.OpenSession();

    using (ITransaction tran = session.BeginTransaction())
    {
        var ret = session.Get<BillingItem>(id);
        tran.Commit();
        return ret;
    }
}

这是我的测试,失败了:

var repo = (IEntityRepository) new SqliteEntityRepository();
var bi1 = repo.GetBillingItemByID(26);
var bi2 = repo.GetBillingItemByID(26);
Assert.AreSame(bi1, bi2); // fails

以下是NHibernateHelper,以防你想看到它:

internal static class NHibernateHelper
{
    private static ISessionFactory _sessionFactory;

    internal static ISession OpenSession()
    {
        return SessionFactory.OpenSession();
    }

    private static ISessionFactory SessionFactory
    {
        get
        {
            if (_sessionFactory == null)
            {
                var configuration = new Configuration();
                configuration.Configure();
                configuration.AddAssembly(typeof(BillingItem).Assembly);
                configuration.AddAssembly(typeof(PaymentItem).Assembly);
                var mapper = new ModelMapper();
                mapper.AddMappings(typeof(Mappings.BillingItemMapping).Assembly.GetExportedTypes());
                mapper.AddMappings(typeof(Mappings.PaymentItemMapping).Assembly.GetExportedTypes());
                var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();
                configuration.AddDeserializedMapping(mapping, null);
                SchemaMetadataUpdater.QuoteTableAndColumns(configuration);
                _sessionFactory = configuration.BuildSessionFactory();
            }

            return _sessionFactory;
        }
    }
}

我在这里缺少什么?

2 个答案:

答案 0 :(得分:2)

这一定是真的,因为在上面的代码片段中,我们正在使用...几乎反模式 ...一个非常短的会话:

using (ISession session = Helpers.NHibernateHelper.OpenSession())
{ ... }

这不是我们通常需要的。我们需要一个工作单元会话。在网络应用程序中,它通常持续整个请求... (在桌面上......应该有一些UoW解决方法)

因此,如果有两个不同的会话 - 那么两者都产生不同的运行时实例。

答案 1 :(得分:1)

存储库不应负责处理事务。您需要有一个工作单元实例,允许您在同一个会话/事务中运行多个查询。

我认为OpenSession()方法每次都会创建一个新会话。你可以为它发布代码吗?