2013-08-28 48 views
0

好吧,讓我說我有一個多對多的學生/類對象。用下面的映射在Nhibernate標準中指定關聯深度

 HasManyToMany(m => m.Classes) 
       .Table("StudentClasses") 
       .LazyLoad() 
       .Cascade.None(); 

和查詢:

 return _session.CreateCriteria<Student>() 
           .Add(Restrictions.Eq("Id", studentId)) 
           .SetCacheable(false) 
           .UniqueResult<Student>(); 

我的表

ID | Student   ID | Class    StudentId | ClassId 
    ============   ===========    =================== 
    1 | John    1 | Algebra    1   | 1 
    2 | Sue    2 | Biology    1   | 2 
    3 | Frank    3 | Speech    2   | 2 
    4 | Jim    4 | Athletics   2   | 5 
    5 | Frankenstein  5 | History    5   | 5 

我要的是約翰,用代數和生物學這來了,但生物學自帶約翰和蘇,她反過來讓我生物和歷史,填補起訴和科學怪人。你不想得到科學怪人(或任何超越生物學的東西)。在任何時候,你都可以開始循環迴圈。

我該如何指定不深入填充? SetMaxRows顯然不是我想要的,因爲它減少了總行數,我只想保溼第一層。我感到特別困惑,因爲我以爲惰性加載將迫使我指定正是我想要滋潤

+0

你怎麼知道John和Sue也回來了? –

回答

1

延遲加載允許您必須指定要滋潤什麼。這些藏品將在您訪問它們時「懶惰地」填充。您的上述查詢只會獲取一行:John。當你訪問john.Classes時,NHibernate將在幕後執行另一個查詢來獲取John的類。然後,當你訪問biology.Students屬性時,NHibernate將執行另一個查詢來填充該集合......等等。

絕對要做想要延遲加載這個關係(這是默認的,順便說一句)。如果你關閉了延遲加載,那麼這就完全符合你想要避免的內容 - NHibernate會知道不允許延遲加載這些集合,所以一旦你加載一個學生就會開始加載它們,這可能最終會加載這三個表中的所有數據,並且以非常低效的方式進行大量數據庫往返。

如果你知道你想要的是「約翰,用代數和生物學」,那麼你應該將這些行添加到您的查詢:

.SetFetchMode("Classes", FetchMode.Eager) 
    .SetResultTransformer(Transformers.DistinctRootEntity) 

SetFetchMode告訴NHibernate的使用左外連接到預填充student.Classes集合。 DistintRootEntity告訴NHibernate不要返回將由左外連接生成的重複學生。