Find top level parent in a list with LINQ

I have a list of custom objects that have an ID and a ParentID. The list looks something like this.

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


I need a LINQ statement to find the top level parent; that is, all objects where ParentID does not exist as an identifier (in this example there are only 123).

Here is what I have so far and am returning 567 678 789.

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



source to share

2 answers

Your current query is trying to find all elements where their id does not match any other parent element id - in other words, you find all childless nodes.

It sounds like what you want is all parent nodes - those whose parent id doesn't match another element id.

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


I am using HashSet<>

to provide reasonable performance .Contains()

for large collections.




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


I use this a lot for small (less than 100,000) collections.

I might as well add this; how easy is it to create a tree view from this:

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)




All Articles