集合上的无效延迟初始化异常
本文关键字:初始化 异常 延迟 无效 集合 | 更新日期: 2023-09-27 18:33:03
我遇到了一个真正令人沮丧的问题,花了几个小时尝试各种方法来解决。当集合延迟加载到某些对象上时,它会抛出一个 LazyInitializationException,指出没有会话或会话已关闭。将代码取出到干净的控制台应用程序中进行测试后 - 我确信会话根本无法关闭!这是代码:
private static ISessionFactory _sessionFactory;
static void Main(string[] args)
{
_sessionFactory = BuildFactory(@"*<ThisIsMyConnectionString>*");
using (var session = _sessionFactory.OpenSession())
{
var allContacts = session.Query<Contact>().Where(x=>x.EmployeeId.HasValue);
foreach (var contact in allContacts)
{
var allServices = contact.EmployeeServices.ToArray();
}
session.Dispose();
}
}
private static ISessionFactory BuildFactory(string connectionString = null)
{
return Fluently.Configure()
.Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008.ConnectionString(connectionString))
.Mappings(m =>
{
m.FluentMappings.Conventions.AddFromAssemblyOf<TableNameConvention>();
m.FluentMappings.AddFromAssemblyOf<KioskAdapterConfigMapping>();
})
.BuildConfiguration().BuildSessionFactory();
}
这是我的(流畅的(映射:
public ServiceMapping()
{
Table("tblServices");
Id(x => x.Id, "ServiceId");
Map(x => x.Name);
}
public ContactMapping()
{
Table("tblContacts");
Id(x => x.Id, "ContactId");
Map(x => x.EmployeeId);
HasManyToMany(x => x.EmployeeServices)
.Table("lnkEmployeeService")
.ParentKeyColumn("EmployeeId")
.PropertyRef("EmployeeId")
.ChildKeyColumn("ServiceId")
.NotFound.Ignore();
}
会议到底是如何结束的?某些数据库记录在"lnkEmployeeService"表中没有任何记录,但所有外键都已就位且有效。此外,链接表确实有额外的列,实际上是与其他列的组合键,但我不关心其余数据。
问题隐藏在以下事实中,即EmployeeServices
集合通过非唯一值"EmployeeId">映射到联系人。
换句话说,让我们假设三个联系人
ContactId, EmployeeId
1 , 1
2 , 2
3 , 2
现在,我们指示 NHibernate 准备就绪,加载 3 个集合。对于每个联系人,它们将/应该/必须是唯一的。因此,在ISession中,它们可以通过其唯一标识符进行保存。在 NOT 属性引用映射的情况下,它们会像:
CollectionId - Collection
1 - the first collection of all Services related to contact with ID 1
2 - the first collection of all Services related to contact with ID 2
3 - the first collection of all Services related to contact with ID 3
但是我们在这里确实有一个问题,因为我们集合的唯一标识符是
CollectionId - Collection
1 ...
2 ...
2 - here we go... this (collection) or the previous
must now be removed from a session...
no way how to load/handle it any more
关键,必须是唯一的,这就是重点,即使这是property-ref
.在文档的不同位置,我们可以看到 5.1.10。多对一:
属性引用属性应仅用于映射旧数据 其中外键引用关联表的唯一键 主键除外。
虽然没有解释<bag>
映射的逻辑仍然相同
我认为问题是您在包装在 using 块中的 IDisposable 上调用 Dispose 的。使用块等效于写入
var myDisposable = new SomeIDisposableImplementation();
try { ... }
finally
{
if(myDisposable != null) myDisposable.Dispose();
}
在您的代码中,"处置"被调用两次。我的猜测是这导致了问题,但我无法在简单的测试中复制异常。