如何使用服务处理NHibernate会话生存期?
在这个问题中,我询问了关于NHibernate会话生存期。 我使用的是桌面应用程序,但是与客户机/服务器分离,所以结论是我将为每个服务器请求使用一个会话,因为服务器端是所有NHibernate魔术发生的地方。
我现在的问题是如何处理它。 当会话过早关闭时,我在加载引用数据时遇到了问题。 问题是我在调试时在被引用的类上看到以下内容 - 因此引用的数据尚未加载:
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;
}
}
事实证明,我在做最后的延迟加载。 我有以下映射:
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(); // <----------
}
}
感谢您的时间,我仍然很乐意看到您对我的结构是否合理的意见。
如果xml文件用于映射目的,我们可以为包设置lazy = false。
链接地址: http://www.djcxy.com/p/43953.html上一篇: How to handle NHibernate session lifetime using services?