在this question中,我询问了NHibernate会话的生命周期。我正在使用桌面应用程序,但是客户端/服务器分离,所以结论是我将每个服务器请求使用一个会话,因为服务器端是所有NHibernate魔法发生的地方。
我现在的问题是如何处理它。当会话过早关闭时,我已经problems before加载了引用的数据。问题是我在调试时在引用的类上看到以下内容 - 因此引用的数据尚未加载:
base {NHibernate.HibernateException} = {“正在初始化[MyNamespace.Foo#14] - 无法初始化角色集合:MyNamespace.Foo.Bars,没有关闭会话或会话”}
据我所知,即使我提交了交易,它也不会加载所有内容。所以我已经知道我需要保持会话开放一段时间,但是多久了?
我的问题基本上是我是否正确处理了生命周期,或者我应该改变什么才能走上正轨。老实说,我看不出这是怎么回事,所以我真正喜欢的是函数调用,以确保获取引用的数据。我不使用延迟加载,所以我认为它们会被立即加载..?
当前架构:使用执行事务的“服务行为”类。这是IDisposable,所以服务本身使用围绕它的using子句。 NHibernateSessionFactory提供了一个静态工厂,因此将被重用。
// This is the service - the function called "directly" through my WCF service.
public IList<Foo> SearchForFoo(string searchString)
{
using (var serviceBehavior = new FooServiceBehavior(new NhibernateSessionFactory()))
{
return serviceBehavior.SearchForFoo(searchString);
}
}
public class FooServiceBehavior : IDisposable
{
private readonly ISession _session;
public FooServiceBehavior(INhibernateSessionFactory sessionFactory)
{
_session = sessionFactory.OpenSession();
}
public void Dispose()
{
_session.Dispose();
}
public IList<Foo> SearchForFoo(string searchString)
{
using (var tx = _session.BeginTransaction())
{
var result = _session.CreateQuery("from Foo where Name=:name").SetString("name", searchString).List<Name>();
tx.Commit();
return result;
}
}
答案 0 :(得分:5)
事实证明我毕竟是在做懒人加载。我有以下映射:
public class FooMapping : ClassMap<Foo>
{
public FooMapping()
{
Not.LazyLoad();
Id(c => c.Id).GeneratedBy.HiLo("1");
Map(c => c.Name).Not.Nullable().Length(100);
HasMany(x => x.Bars).Cascade.All();
}
}
我假设Not.LazyLoad()
禁用了延迟加载,但显然不适用于引用的对象。我在引用上添加了延迟加载,这似乎解决了这个问题。
public class FooMapping : ClassMap<Foo>
{
public FooMapping()
{
Not.LazyLoad();
Id(c => c.Id).GeneratedBy.HiLo("1");
Map(c => c.Name).Not.Nullable().Length(100);
HasMany(x => x.Bars).Not.LazyLoad(); // <----------
}
}
感谢您的时间,我仍然很高兴看到您对我的特定结构是否合理的看法。
答案 1 :(得分:-1)
如果xml文件用于映射目的,我们可以为包设置lazy = false。