2009-06-02 126 views
24

我想加載根實體並加載所有它的子集合和聚合成員。渴望加載與NHibernate的子集合

一直在嘗試在FluentNHibernate中使用SetFetchMode,但由於我有3個層次的深度,因此我在其中一個子集合中獲取了重複項。 DistinctRootEntityResultTransformer不幸的是只能刪除根重複。

return Session.CreateInvoiceBaseCriteria(query, archived) 
    .AddOrder(new Order(query.Order, query.OrderType == OrderType.ASC)) 
    .SetFetchMode("States", FetchMode.Eager) 
    .SetFetchMode("Attestations", FetchMode.Eager) 
    .SetFetchMode("AttestationRequests", FetchMode.Eager) 
    .SetFetchMode("AttestationRequests.Reminders", FetchMode.Eager) 
    .SetResultTransformer(new DistinctRootEntityResultTransformer()) 
    .List<Invoice>(); 

我可以使用多個查詢或類似的東西來歸檔嗎?

此外,這種方法不會導致數據庫中不必要的巨大結果集嗎?

有什麼建議嗎?

回答

0

雖然它可能不是你在尋找什麼,我會建議在看這篇文章:

Eager loading aggregate with many child collections

如果你看看周圍的網站的其餘部分,你會發現更多的職位,討論急切的加載和其他偉大的nHibernate的東西。

+2

確實是一篇很好的文章,但不確定我是否可以將其應用於我的情況。在關於急切加載特定根實體的文章中描述的解決方案中,我的問題是我想加載一組根實體。如果我使用MultiCritera,我需要找到一種方法來連接所有不同的查詢,而無需指定特定的實體。建議如何做到這一點? – Kristoffer 2009-06-02 11:46:28

+0

該示例只有一個額外的層次結構級別,但沒有孫子,MultiQuery/MultiCriteria似乎完全無用,因爲後面的查詢無法引用先前查詢的結果(如Query#1:select rootObjects r left join fetch children c其中...;查詢#2:選擇孫的父母在c)。 – 2012-05-30 10:09:52

8

找到了一個解決方案,但它不漂亮。首先,我去查找所有發票ID,然後在多查詢中使用它們,最後通過HashedSet過濾結果。由於大量的項目有時我不能使用Normalt Restriction.In並被迫將其作爲字符串發送。

任何建議的調整?

var criteria = Session.CreateInvoiceBaseCriteria(query, archived) 
    .SetProjection(Projections.Id()); 

var invoiceIds = criteria.List<int>(); 
if (invoiceIds.Count > 0) 
{ 
    var joinedIds = JoinIDs(criteria.List<int>()); // To many ids to send them as parameters. 

    var sql1 = string.Format("from Invoice i inner join fetch i.States where i.InvoiceID in ({0}) order by i.{1} {2}", joinedIds, query.Order, query.OrderType.ToString()); 
    var sql2 = string.Format("from Invoice i inner join fetch i.AttestationRequests where i.InvoiceID in ({0})", joinedIds); 
    var sql3 = string.Format("from Invoice i inner join fetch i.Attestations where i.InvoiceID in ({0})", joinedIds); 

    var invoiceQuery = Session.CreateMultiQuery() 
     .Add(sql1) 
     .Add(sql2) 
     .Add(sql3); 

    var result = invoiceQuery.List()[0]; 

    return new UniqueFilter<Invoice>((ICollection)result); 
} 

return new List<Invoice>(); 
2

要回答你的問題:是的,它會導致巨大的結果集。

我建議:

  • 只是天真地寫你的查詢,而渴望獲取
  • 在某些地方,把一個預先抓取,但如果你真正得到的性能問題,只有每個查詢
  • 一個你無法通過索引或通過增強查詢和映射策略來解決問題,請使用具有多個查詢的解決方案。