2011-03-05 57 views
4

場景: 我有數據庫表,存儲另一個表的多對多關係的層次結構。一個項目可以有多個子項,也可以有多個父項。遞歸Linq分組

Items  
------ 
ItemID (key) 

Hierarchy 
--------- 
MemberID (key) 
ParentItemID (fk) 
ChildItemID (fk) 

樣品層次:

Level1 Level2 Level3 
X  A  A1 
       A2 
     B  B1 
       X1 
Y  C 

我想組中的所有節點通過層次結構中的每一個節點。

Parent Child 
X  A1 
     A2 
     B1 
     X1 
A  A1 
     A2 
B  B1 
     X1 
Y  C 
  • 請注意有在父列中沒有葉節點,以及如何將兒童柱只有包含葉節點。
  • 理想情況下,我希望結果爲IEnumerable < IGrouping<項目,項目>>其中關鍵是一個父項和組項目都是子項。
  • 理想情況下,我想要一個解決方案,實體提供者可以將其轉換爲T-SQL,但如果這不可行,那麼我需要將往返次數減少到最少。
  • 我打算在葉節點上加入另一個表中存在的Sum值。

回答

1

因爲你總是會被返回表中的所有項目,爲什麼不只是使得到所有孩子的家長遞歸方法,然後使用上內存的項目:

partial class Items 
{ 
    public IEnumerable<Item> GetAllChildren() 
    { 
     //recursively or otherwise get all the children (using the Hierarchy navigation property?) 
    } 
} 

則:

var items = 
    from item in Items.ToList() 
    group new 
    { 
     item.itemID, 
     item.GetAllChildren() 
    } by item.itemID; 

對不起任何語法錯誤......

+0

謝謝你的發表!我以類似的方式實現了遞歸。 (+1)它適用於單元測試,但我仍然需要根據數據庫進行測試。如果它運作良好,我會接受你的答案。 – 2011-03-07 02:10:25

0

好吧,如果層次結構是嚴格的2級可以隨時工會他們,讓LINQ理清SQL(它最終被行程單雖然它需要看到它有多快你的捲上運行數據):

var glist = from pc in hlist.AsEnumerable() 
      group pc.Child by pc.Parent into g 
      select new { Parent = g.Key, Children = g }; 

我以前AsEnumerable()這裏我們到達LINQ SQ的能力:

var hlist = from h in Hierarchies 
      select new {h.Parent, h.Child}; 

var slist = from h in Hierarchies 
      join h2 in hlist on h.Parent equals h2.Child 
      select new {h2.Parent, h.Child}; 

hlist = hlist.Union(slist); 

所以如果你想將它們分組,你只要按照這給你一個平IEnumerable<{Item, Item}>列表L提供商嘗試將聯盟分組。如果您嘗試使用IQueryable,它會針對可資格的父母運行基本聯盟,然後爲每位父母進行往返(這是您想要避免的)。無論您是否使用常規的LINQ進行分組都取決於您,相同的數據量將不得不以任何方式通過管道。

編輯:或者,你可以建立一個視圖鏈接到所有其子女的父視圖,並使用該視圖作爲綁定項目的基礎。從理論上講,這應該允許你/ L2S在一次旅行中對它進行分組。

+0

我喜歡你的答案,但會有至少4個級別和層次結構將表驅動(用戶配置的),所以有在運行時可以是任意數量的級別。出於這個原因,我會嘗試使用遞歸,但是我擔心往返會影響性能。我會稍後跟進。 – 2011-03-07 02:22:17

+0

你的等級有多大?如果你想減少往返旅行,我認爲你應該考慮一下這個linq框。您可能想要探索的一些選項: 1.使用sql server層次結構支持並構建視圖以生成結果,您將在一次調用中獲取結果 2.如果層次結構表不是太大,只需加載整個結果在一勺,並建立一個層次結構分組客戶端? – mmix 2011-03-07 10:42:59