这是我的理解 - 例如来自First and Second Level caching in NHibernate之类的来源 - 当使用“默认”设置 - 会话等时,NHibernate的ISession.get<T>(object id)
应该返回相同的实例,如果使用相同的id
调用两次。但是,我有两个不同的实例。
我看到过类似的问题,但this和this等搜索没有有用的结果。
这是我的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;
}
}
}
我在这里缺少什么?
答案 0 :(得分:2)
这一定是真的,因为在上面的代码片段中,我们正在使用...几乎反模式 ...一个非常短的会话:
using (ISession session = Helpers.NHibernateHelper.OpenSession())
{ ... }
这不是我们通常需要的。我们需要一个工作单元会话。在网络应用程序中,它通常持续整个请求... (在桌面上......应该有一些UoW解决方法)。
因此,如果有两个不同的会话 - 那么两者都产生不同的运行时实例。
答案 1 :(得分:1)
存储库不应负责处理事务。您需要有一个工作单元实例,允许您在同一个会话/事务中运行多个查询。
我认为OpenSession()
方法每次都会创建一个新会话。你可以为它发布代码吗?