如何使用服务处理NHibernate会话生命周期?

sti*_*k81 7 .net c# nhibernate session lazy-loading

这个问题中,我询问了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; 
        }
    }
Run Code Online (Sandbox Code Playgroud)

sti*_*k81 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我假设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(); // <----------
    }
}
Run Code Online (Sandbox Code Playgroud)

感谢您的时间,我仍然很高兴看到您对我的给定结构是否合理的看法.