我有一个具有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();
答案 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();