使用LINQ在List中查找顶级父级

时间:2015-05-08 21:29:40

标签: c# linq

我有一个具有ID和ParentID的用户定义对象列表。列表看起来像这样。

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();

2 个答案:

答案 0 :(得分: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()效果。

答案 1 :(得分:3)

此外:

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

我在小型(少于100,000个)收藏中使用了很多。

我也可以加上这个;如何从这里轻松创建树视图:

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();