LINQ recursive query to return hierarchical set of groups
So first, your TeamGrouping
is actually a bit more complex than it needs to be. All it needs is the Team
object and a sequence of itself for children:
public class TeamNode
{
public Team Value { get; set; }
public IEnumerable<TeamNode> Children { get; set; }
}
Next we'll take our sequence of teams and create a node for each one. Then we'll use ToLookup
to group them by their parent ID. (Your use of GroupBy
is pretty darn close to this, but ToLookup
will be easier.) Finally we can just set each node's children to be the lookup value for that node (note that ILookup
will return an empty sequence if the key doesn't exist, so our leaves will be handled perfectly). To finish it off we can return all of the top level nodes by just looking up all nodes with a parent ID of null
.
public static IEnumerable<TeamNode> CreateTree(IEnumerable<Team> allTeams)
{
var allNodes = allTeams.Select(team => new TeamNode() { Value = team })
.ToList();
var lookup = allNodes.ToLookup(team => team.Value.ParentTeamId);
foreach (var node in allNodes)
node.Children = lookup[node.Value.TeamId];
return lookup[null];
}