DavidB
DavidB

Reputation: 2596

Linq to recurse through a hierarchy

I have a heirarchical data structure as follows.

TABLE 1

id | Groupname | parentId

TABLE 2

id | nodeName | parentId

Table 1 parentId refers to table1 Id, and table2 parentId also refers to table 1 id.

Starting at any ID in table 1, I need to print out all the nodes, and then traverse through the children of all child groups.

Up to now I have this

int id = 1; // replace with argument

repository.Nodes.Where(n => n.ParentId == Id).ToList().ForEach(d =>
{
  result.NodeList.Add(GetNodeDetails(n.Id));
});

Can anyone help me get this looping through in nice efficent linq manner?

Upvotes: 1

Views: 1410

Answers (1)

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174289

If I understand you correctly you want to flatten the hierarchy, i.e. the end result should be one flat list with all children of all hierarchy levels.

The simplest way to achieve this is through recursion:

private IEnumerable<Node> GetSelfAndChildren(Node node)
{
    yield return GetNodeDetails(n.Id);
    foreach(var c in n.Children.SelectMany(GetSelfAndChildren)
        yield return c;
};


var result = repository.Nodes.Where(n => n.ParentId == Id)
                       .AsEnumerable()
                       .SelectMany(GetSelfAndChildren)
                       .ToList();

This uses a recursive method to get a flat list of children.

This approach has the potential to exhibit the N+1 problem. Depending on the configuration each access of Children will cause a roundtrip to the database.
If the N+1 problem is happening and causing - well - problems, an alternative approach would be to first fetch all nodes from the database and then perform a Breadth-first search.

Upvotes: 5

Related Questions