2010-01-08 70 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