2010-04-01 111 views
3

我有兩列,groupId和的ParentId(均爲GUID)的一個表。該表形成一個層次結構,因此我可以在「GroupId」字段中查找值,當我找到它時,我可以查看它的ParentId。此ParentId也將出現在不同記錄的GroupId中。我可以使用它從任何點到根(root是一個空的GUID)遍歷層次結構樹。當我知道一個GroupId時,我想要做的是獲取記錄列表。這將是GroupId和所有父母回到根記錄的記錄。 Linq有可能嗎?如果有的話,任何人都可以提供代碼片段嗎?散步層次結構表使用LINQ

回答

5

LINQ是不是設計來處理遞歸選擇。

當然可以編寫自己的擴展方法,爲在LINQ到補償對象,但我發現,LINQ到實體不喜歡的功能並不容易轉換成SQL。

編輯: 有趣的是,LINQ到實體不抱怨馬特·沃倫的採取上使用LINQ here遞歸。你可以這樣做:

var result = db.Table.Where(item => item.GroupId == 5) 
        .Traverse(item => db.Table.Where(parent 
                 => item.ParentId == parent.GroupId)); 

使用這裏定義的擴展方法:

static class LinqExtensions 
{ 
    public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, 
              Func<T,IEnumerable<T>> selector){ 
    foreach(T item in source){ 
     yield return item; 
     IEnumerable<T> children = selector(item); 
     foreach (T child in children.Traverse(selector)) 
     { 
      yield return child; 
     } 
    } 
} 

服務表現可能不佳,但。

1

它使用LINQ絕對有可能的,但你必須做一個DB呼籲在層級結構中每個級別。不完全最佳。

0

其他受訪者是正確的 - 表現將是對這個非常糟糕的,因爲你必須做出多次往返。然而,這將取決於您的具體情況 - 例如,您的樹很深並且會經常執行此操作。

您可以創建存儲過程,這是否(使用CTE),並且包裝它在實體設計來回報您的特別定義的實體得到更好的服務。

+0

你能指點我一些關於如何做到這一點的信息的方向嗎? – Evildommer5 2013-08-30 08:44:49