给出以下模型列表
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<Team> ChildTeams { get; set; }
public IEnumerable<TeamGrouping> Grouping { get; set; }
}
private IEnumerable<TeamGrouping> ToGrouping(IEnumerable<Team> teams)
{
return teams.GroupBy(t => t.ParentTeamId, (parentTeam, childTeams) => new TeamGrouping {ParentTeamId = parentTeam, ChildTeams = childTeams});
}
private IEnumerable<TeamGrouping> ToGrouping(IEnumerable<TeamGrouping> teams)
{
return teams.GroupBy(t => t.ParentTeamId, (parentTeam, childTeams) => new TeamGrouping{ParentTeamId = parentTeam, Grouping = childTeams});
}
我会将团队列表传递给第一个ToGrouping(IEnumerable<Team>)
,然后将后续返回的组传递到ToGrouping(IEnumerable<TeamGrouping>)
,但这会产生错误的结果。
任何人都有任何建议或想法吗?
答案 0 :(得分:4)
首先,你的TeamGrouping
实际上比它需要的要复杂一点。它需要的只是Team
对象及其自身的序列:
public class TeamNode
{
public Team Value { get; set; }
public IEnumerable<TeamNode> Children { get; set; }
}
接下来,我们将采用我们的团队序列并为每个团队创建一个节点。然后我们将使用ToLookup
按父ID进行分组。 (您对GroupBy
的使用非常接近,但ToLookup
会更容易。)最后,我们可以将每个节点的子节点设置为该节点的查找值(请注意{{1}如果密钥不存在,将返回一个空序列,因此我们的叶子将被完美处理)。为了完成它,我们可以通过查找父ID为ILookup
的所有节点来返回所有顶级节点。
null
答案 1 :(得分:0)
首先,您需要一个这样的对象,因此Team对象可能是:
public class Team
{
public ParentId {get;set;}
public IEnumerable<Team> ChildTeams{get;set;}
}
然后是递归函数
private IEnumerable<Team> BuildTeams(IEnumerable<Team> allTeams,
int? parentId)
{
var teamTree = new List<Team>();
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
为父母,并且会拉出所有拥有空父母的球队:),虽然我注意到你的球队没有父母的空,所以不知道如何你现在确定了顶级的那些?
答案 2 :(得分:0)
使用Entity Framework对象时的另一种解决方案是,可以通过删除第一次调用时父级为空的Team对象来处理根对象(Parent == null)。
public class Team
{
int TeamID { get; set; }
Team Parent; { get; set; }
}
public class TeamNode
{
public Team Node { get; set; }
public IEnumerable<TeamNode> Children { get; set; }
}
private List<Team> BuildTeams(List<Team> allTeams, int? parentId)
{
List<TeamNodes> teamTree = new List<Team>();
List<Team> childTeams;
if (parentId == null)
{
childTeams = allTeams.Where(o => o.Parent == null).ToList();
allTeams.RemoveAll(t => t.Parent == null);
}
else
{
childTeams = allTeams.Where(o => o.Parent.ID == parentId).ToList();
}
foreach (Team team in childTeams)
{
TeamNode teamNode = new Team();
teamnode.Node = team;
List<TeamNode> children = BuildTeams(allTeams, team.TeamID);
teamNode.ChildTeams = children;
teamTree.Add(t);
}
return teamTree ;
}