LINQ递归查询返回分层的组集
给出以下模型的列表
public class Team { public int TeamId { get; set; } public int ParentTeamId { get; set; } }
我正在尝试编写一个递归的linq查询,这将使我能够检索看起来像这样的层次结构
Team ChildTeams Team Team ChildTeams
我尝试了很多方法并看到了许多类似的问题,但没有一个能够帮助我解决问题。 我尝试的最新尝试遵循以下方针:
private class TeamGrouping { public int? ParentTeamId { get; set; } public IEnumerable ChildTeams { get; set; } public IEnumerable Grouping { get; set; } } private IEnumerable ToGrouping(IEnumerable teams) { return teams.GroupBy(t => t.ParentTeamId, (parentTeam, childTeams) => new TeamGrouping {ParentTeamId = parentTeam, ChildTeams = childTeams}); } private IEnumerable ToGrouping(IEnumerable teams) { return teams.GroupBy(t => t.ParentTeamId, (parentTeam, childTeams) => new TeamGrouping{ParentTeamId = parentTeam, Grouping = childTeams}); }
我会将团队列表传递给第一个ToGrouping(IEnumerable)
,然后将后续返回的组ToGrouping(IEnumerable)
给ToGrouping(IEnumerable)
但这会产生不正确的结果。
任何人有任何建议或想法?
首先,你的TeamGrouping
实际上比它需要的要复杂一些。 它需要的只是Team
对象及其自身的序列:
public class TeamNode { public Team Value { get; set; } public IEnumerable Children { get; set; } }
接下来,我们将采用我们的团队序列并为每个团队创建一个节点。 然后我们将使用ToLookup
按父ID分组。 (你对GroupBy
使用非常接近于此,但ToLookup
会更容易。)最后,我们可以将每个节点的子节点设置为该节点的查找值(请注意,如果键不是,则ILookup
将返回空序列存在,所以我们的叶子将被完美处理)。 为了完成它,我们可以通过查找父ID为null
所有节点来返回所有顶级节点。
public static IEnumerable CreateTree(IEnumerable 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]; }
首先你需要一个像这样的对象,所以Team对象可能是:
public class Team { public ParentId {get;set;} public IEnumerable ChildTeams{get;set;} }
然后是递归函数
private IEnumerable BuildTeams(IEnumerable allTeams, int? parentId) { var teamTree = new List (); var childTeams = allTeams.Where(o => o.ParentId == parentId).ToList(); foreach (var team in childTeams) { var t = new Team(); var children = BuildTeams(allTeams, team.TeamID); t.ChildTeams = children; teamTree.Add(t); } return teamTree ; }
第一个调用为父级传递一个null
,并且将拉出所有具有null父级的团队:),虽然我注意到你的团队没有父级的null,所以不确定你如何识别当前的顶级队员?