2009-09-15 39 views
0

我有一棵樹,每一個節點是資源類:NHibernate的一個一對多的關係,延遲加載的時候就已經加載

public abstract class Resource 
{ 
     public virtual Guid Id { get; set; } 
     public virtual Resource Parent { get; set; } 
     public virtual IList<Resource> ChildResources { get; set; } 
} 

,你可以看到這個類是抽象的,也有來自許多不同的派生類資源(目前3個,更多)。

在我的數據庫中,我有一個資源表,以及 從Resource派生的每個類的表。這些映射在一起<joined-subclass>

我讀過這樣的:

http://ayende.com/Blog/archive/2009/08/28/nhibernate-tips-amp-tricks-efficiently-selecting-a-tree.aspx

和我有相同的代碼Ayende加載我的樹:

var resource = UnitOfWork.Current.Session 
    .CreateQuery("from Resource r join fetch r.ChildResources") 
    .SetResultTransformer(new DistinctRootEntityResultTransformer()) 
    .SetReadOnly(true) 
    .List<Resource>(); 

這是所有工作的罰款(所有的資源都可返回一個選擇)但是,我看到額外的選擇發生,因爲我枚舉資源的ChildResources列表。

就是因爲這一點,?:

http://ayende.com/Blog/archive/2009/09/03/answer-the-lazy-loaded-inheritance-many-to-one-association-orm.aspx

無論哪種方式,我該如何避免這種情況的發生?

這裏的(修剪爲清楚起見類名 )的關係的映射的一部分:

<bag cascade="save-update" fetch="join" lazy="false" inverse="true" name="ChildResources"> 
     <key> 
       <column name="Parent_Id" /> 
     </key> 
     <one-to-many class="Resource" /> 
</bag> 
<many-to-one class="Resource" name="Parent"> 
     <column name="Parent_Id" /> 
</many-to-one> 

感謝

UPDATE

稍有疏忽,其僅發行額外的選擇時枚舉樹中葉節點的子集合...

+0

什麼是你看到的選擇? – Mark 2009-09-15 10:49:04

+0

'joined-subclasses'的'left join'的第一個'select'返回所有資源。額外的選擇是我期望在懶惰負載情況下看到的; '選擇資源where parent_id = foo' – 2009-09-15 12:18:21

+0

看到我的更新q – 2009-09-15 12:29:46

回答

0

做這一點:

<bag ... lazy="false"> 

到預先抓取物品始終,或做到這一點(在HQL):

var resources = session.CreateQuery("from Resource r join fetch r.ChildResources"); 
+0

lazy = false沒有區別,這就是我使用的HQL。當這個HQL被執行時,我得到了所有從數據庫返回的資源行,但是:)當我枚舉ChildResources時,它再次點擊數據庫「從資源中選擇Parent_id ='' – 2009-09-15 09:21:23

+0

我更新了問題反映這一點,還有其他一些發現 – 2009-09-15 12:30:19