2010-01-08 106 views
7

this question我询问了NHibernate会话生存期。我使用的是桌面应用程序,但是与客户机/服务器分离,所以结论是我将为每个服务器请求使用一个会话,因为服务器端是所有NHibernate魔术发生的地方。如何使用服务处理NHibernate会话生存期?

我现在的问题是如何处理它。当会话过早关闭时,我有problems before加载引用数据。的问题是,有人在我的被引用类下面调试时 - 因此所引用的数据是尚未加载:

基{NHibernate.HibernateException} = {“初始化[MyNamespace.Foo#14] -failed懒洋洋地初始化角色的集合: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; 
     } 
    } 

回答

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

如果将xml文件用于映射目的,我们可以为包设置lazy = false。

+0

XML文件不用于映射 - 正如您在示例代码中看到的那样。我使用Fluent进行映射。 – stiank81 2010-02-26 08:34:02