2015-05-08 95 views
3

我有一個用戶定義的對象列表,其中包含一個ID和一個ParentID。該列表看起來像這樣。在LINQ中查找列表中的頂級父節點

ParentID  ID 
    123  345 
    123  456 
    456  567 
    456  678 
    678  789 

我需要一個LINQ語句來查找頂級父級;也就是說,ParentID不存在的所有對象都作爲ID存在(本例中僅爲123)。

這是我到目前爲止,它正在返回567,678,789。

parentList = baseList.Where(b => !baseList.Select(o => o.ParentID).Distinct().Contains(b.ID)).ToList(); 
+0

如果沒有人回答這個問題,我會在沒有移動時觸及它。你會想加入清單,而不是針對它本身。你現在擁有的是超低效率的,它會重建每次迭代的IDES枚舉。完整的語法後面,如果沒有人拿起這個評論:-) – VulgarBinary

回答

4

您當前的查詢正試圖找到所有的地方ID不符合任何其他項目的父ID的項目 - 換句話說,你發現所有沒有孩子的節點。

它聽起來像你想要的是所有無父節點 - 父母的ID不匹配任何其他項目的ID。

var ids = new HashSet<int>(baseList.Select(o => o.ID)); 
var itemsWithNoParent = baseList.Where(o => !ids.Contains(o.ParentID)) 
    .ToList(); 

我使用HashSet<>,以確保大集合合理.Contains()性能。

3

另外:

parentList = baseList 
    .where(parent => !baseList.Any(possibleParent => possibleParent.ID == parent.ParentID)) 
    .ToList(); 

我用這個有很多小(不到10萬)的集合。

我不妨補充一點;如何輕鬆創建樹視圖:

public class Node 
{ 
    public int Id { get; set; } 
    public int ParentId { get; set; } 
    public IEnumerable<Node> Nodes { get; set; } 
    public Node ParentNode { get; set; } 
} 

IEnumerable<Node> nodes = ..... 

nodeTree = nodes.Select(n => 
{ 
    n.Nodes = nodes.Where(n2 => n2.ParentId == n.Id).ToList(); 
    n.ParentNode = nodes.FirstOrDefault(n2 => n2.Id == n.ParentId) 
    return n; 
}) 
.Where(n => n.ParentNode == null) 
.ToList(); 
+0

什麼是'孩子'? – StriplingWarrior

+1

哈!更新.... :) –

+0

我喜歡單獨的聲明 – joelforsyth