简体   繁体   English

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

[英]Calling NHibernate ISession.get<T>(object id) twice with the same id returns two different instances

It's my understanding -- eg from sources like First and Second Level caching in NHibernate -- that NHibernate's ISession.get<T>(object id) should, when using the "default" setup -- session, etc., return the same instance if called twice with the same id . 这是我的理解 - 例如来自NHibernate中的第一级和第二级缓存之类的资源 - 当使用“默认”设置 - 会话等时,NHibernate的ISession.get<T>(object id)应返回相同的实例如果使用相同的id调用两次。 However, I'm getting two separate instances. 但是,我有两个单独的实例。

I've seen vaguely-similar questions but no useful results with searches like this , and this . 我已经看到了依稀相似的问题,但与像搜索任何有用的结果这个这个

Here's my get method: 这是我的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;
    }
}

Here's my test, which is failing: 这是我的测试,它失败了:

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

Here's NHibernateHelper just in case you want to see it: 这是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;
        }
    }
}

What am I missing here? 我在这里错过了什么?

This must be true, because in a snippet above we are using ... almost anti-pattern ... a very short session: 这必须是真的,因为在上面的代码片段中我们正在使用...几乎反模式 ...一个非常短的会话:

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

That is not what we usually need. 这不是我们通常需要的。 We need a Unit of Work session. 我们需要一个工作单元会议。 In web app, it usually last through whole request... (In a desktop... there should be some UoW workaround) . 在网络应用程序中,它通常持续整个请求... (在桌面上......应该有一些UoW解决方法)

So, if there are two different sessions - then both produce different run-time instance. 因此,如果有两个不同的会话 - 那么两个会产生不同的运行时实例。

Repositories should not be responsible for handling transactions. 存储库不应负责处理事务。 You need to have a single instance of unit of work that would allow you to run multiple queries in the same session/transaction. 您需要具有单个工作单元实例,以允许您在同一会话/事务中运行多个查询。

It looks to me that the OpenSession() method creates a new session each time. 在我看来, OpenSession()方法每次都会创建一个新会话。 Can you post the code for it? 你能为它发布代码吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Moq NHiberNate ISession.Get不调用模拟会话对象 - Moq NHiberNate ISession.Get doesn't call mock session object 带有复合键的实体上的NHibernate ISession.Get()引发InvalidCastException - NHibernate ISession.Get() on entity with composite key throws InvalidCastException 使用NHibernate的ISession.Get &lt;&gt;()w /复合键 - Using NHibernate's ISession.Get<>() w/ a composite key NHibernate ISession.QueryOver()不能推断类型,但是ISession.Get()可以。为什么? - NHibernate ISession.QueryOver() cannot infer type but ISession.Get() can.. Why is this? Nhibernate Linq获取 <T> 按名称而不按ID的对象 - Nhibernate Linq Get<T> object by name not by Id 在“ ISession.Refresh”上,NHibernate在会话缓存上为同一数据库记录生成两个实例。 为什么以及如何解决? - On 'ISession.Refresh' NHibernate generates two instances for the the same database record on the Session Cache. Why and how to solve it? Nhibernate不更新对象ID - Nhibernate doesn't update object id NHibernate维护Isession对象的方法 - NHibernate approach to maintain Isession object 在NHibernate中通过ID或父对象获取子对象? - Get child objects by id or parent object in NHibernate? NHibernate映射对象到使用相同ID的多个表? - NHibernate map object to multiple tables using same Id?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM