2016-02-22 24 views
2

我有一個大的後臺數據庫,裏面有我使用下面的類結構:獲取LINQ列表中的所有子項

public class InputClass 
{ 
    public int id { get; set; } 
    public string text { get; set; } 
    public string icon { get; set; } 
    public int? parentId { get; set; } 
} 

正如你所看到的,每個元素都可以有一個父ID,其中最終生成一個用戶可以與之交互的樹形式的信息列表。

使用下面的示例數據爲例:

var inputList = new List<InputClass>(); 
inputList.Add(new InputClass() { id = 1, text = "Item #1"}); 
inputList.Add(new InputClass() { id = 2, text = "Item #2" }); 
inputList.Add(new InputClass() { id = 3, text = "Item #3" }); 
inputList.Add(new InputClass() { id = 4, text = "SubItem #1", parentId = 1 }); 
inputList.Add(new InputClass() { id = 5, text = "SubItem #2", parentId = 1 }); 
inputList.Add(new InputClass() { id = 6, text = "SubItem #3", parentId = 2 }); 
inputList.Add(new InputClass() { id = 7, text = "Sub-Sub Item #1", parentId = 4 }); 

我想傳遞一個ID#和檢索所有標記了的parentID的元素的列表。舉例來說,如果我有1 ID號,結果應該是如下:

ID Name 
4 Subitem #1 
5 Subitem #2 
7 Sub-Sub Item #1 

,你可以看到,其結果應該返回位於ID#1的下方,包括ID#7(項目一切即使它具有4的父母ID,項目4的父母也是#1)。

我希望以上內容有意義,關於如何在LINQ中實現這一點的任何想法?

+1

你到目前爲止嘗試過什麼?你目前的最佳嘗試是什麼樣子?它返回什麼? – mech

+1

[Recursive Hierarchy - 使用Linq遞歸查詢]的可能重複(http://stackoverflow.com/questions/20974248/recursive-hierarchy-recursive-query-using-linq) – danish

+0

爲什麼它必須是LinQ?你可以使用遞歸函數這種情況。 – Sakura

回答

4

Recursive方法。

public static IEnumerable<InputClass> Recursive(List<InputClass> items, int toplevelid)  
{ 
    List<InputClass> inner = new List<InputClass>(); 
    foreach (var t in items.Where(item=>item.parentId ==toplevelid)) 
    { 
     inner.Add(t); 
     inner = inner.Union(Recursive(items, t.id)).ToList(); 
    }  

    return inner; 
} 

工作Demo

+0

不會失敗,如果一個孩子創建下一個級別? inputList.Add(new InputClass(){id = 8,text =「Sub-Sub Item#1」,parentId = 7}); – Rangesh

+0

這是真的,忽略了這種情況。將相應修改。 –

2

在這種情況下:

static bool IsParent(IEnumerable<InputClass> lc, InputClass ic, int? ParentID) 
{ 
    return ic.parentId != null ? ic.parentId == ParentID || IsParent(lc, lc.First(o => o.id == ic.parentId), ParentID) : false; 
} 

int? id = 1; // Parent ID 
foreach(var i in inputList) 
{ 
    if(IsParent(inputList, i, id))) 
    { 
     // get this item 
    } 
} 


其他方式:

static IEnumerable<InputClass> getAllChildren(IEnumerable<InputClass> lc, int? ParentID) 
{ 
    foreach (var i in lc) 
    { 
     if (i.parentId == ParentID) 
     { 
      yield return i; 
      foreach (var i2 in getAllChildren(lc, i.id)) yield return i2; 
     } 
    } 
} 

int? id = 1; // Parent ID 
foreach (var i in getAllChildren(inputList,id)) 
{ 
    // Get this Item 
} 
2
static class Program 
    { 
     public static void Main() 
     { 

      IEnumerable<InputClass> allItems = someBLL.GetAllItems(); 

      int? someParentNode = 1; 

      var allChildItems = InputClass.GetAllChildNodesRecursivrly(someParentNode, allItems); 

     } 
    } 

    public class InputClass 
    { 
     public int id { get; set; } 
     public string text { get; set; } 
     public string icon { get; set; } 
     public int? parentId { get; set; } 

     public static IEnumerable<InputClass> GetAllChildNodesRecursivrly(int? ParentId,IEnumerable<InputClass> allItems) 
     { 
      var allChilds = allItems.Where(i => i.parentId == ParentId); 

      if (allChilds==null) 
      { 
       return new List<InputClass>(); 
      } 

      List<InputClass> moreChildes = new List<InputClass>(); 
      foreach (var item in allChilds) 
      { 
       moreChildes.AddRange(GetAllChildNodesRecursivrly(item.id,allItems)); 
      } 

      return allChilds.Union(moreChildes); 
     } 
    } 
-2

我認爲你需要寫的是一個lambda表達式。

var results = inputList.Where(x => x.parentId == 1) 
+0

這不採取多層次的孩子的情況 – Sakura