LINQ递归查询返回分层组集 [英] LINQ recursive query to return hierarchical set of groups

查看:176
本文介绍了LINQ递归查询返回分层组集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于下列型号列表



 公共类团队
{
公众诠释TeamId {得到;组; }
公众诠释ParentTeamId {搞定;组; }
}



我想写一个递归LINQ查询,这将使我找回一个层次结构,看起来像这样

 团队
ChildTeams


ChildTeams

我试过很多方法和见过很多类似的问题,但他们没有专门帮我解决了问题。

 私有类TeamGrouping 
{
公众诠释:我试过的最新尝试沿着这些路线去? ParentTeamId {搞定;组; }
公开的IEnumerable<团队及GT; ChildTeams {搞定;组; }
公开的IEnumerable< TeamGrouping>分组{搞定;组; }
}

私人的IEnumerable< TeamGrouping> ToGrouping(IEnumerable的<团队及GT;团队)
{
返回teams.GroupBy(T => t.ParentTeamId,(parentTeam,childTeams)=>新建TeamGrouping {ParentTeamId = parentTeam,ChildTeams = childTeams}) ;
}

私人的IEnumerable< TeamGrouping> ToGrouping(IEnumerable的< TeamGrouping>团队)
{
返回teams.GroupBy(T => t.ParentTeamId,(parentTeam,childTeams)=>新建TeamGrouping {ParentTeamId = parentTeam,分组= childTeams}) ;
}



我的球队名单传递到第一个 ToGrouping(IEnumerable的<团队及GT;)然后随后返回群体纳入 ToGrouping(IEnumerable的< TeamGrouping>)但这是产生不正确的结果。

任何人有任何建议或想法?


解决方案

因此,首先,你的 TeamGrouping 实际上是更复杂一点比它需要。它所需要的是团队对象本身对儿童的序列:

 公共类TeamNode 
{
公共球队价值{搞定;组; }
公开的IEnumerable< TeamNode>儿童{搞定;组; }
}



接下来,我们将利用我们团队的序列,并为每个节点一。然后,我们将通过它们的父ID使用 ToLookup 将它们分组。 (您使用 GROUPBY 是相当的接近这一点,但 ToLookup 会更容易。)最后,我们可以只设置每个节点的孩子是该节点的查找值(注意, ILookup 会返回一个空序列,如果该键不存在,所以我们的叶片会被完全处理)。为了完成它,我们可以通过看与的父ID的所有节点返回所有顶级节点。

 公共静态的IEnumerable< TeamNode> CreateTree(IEnumerable的<团队及GT; allTeams)
{
VAR allnodes中= allTeams.Select(团队=>新建TeamNode(){值=队})
.ToList();
VAR查找= allNodes.ToLookup(团队=> team.Value.ParentTeamId);
的foreach(在allnodes中VAR节点)
node.Children =查找[node.Value.TeamId]
返回查找[空]
}


Given a list of the following models

public class Team
{
    public int TeamId { get; set; }
    public int ParentTeamId { get; set; }
}

I am trying to write a recursive linq query which will enable me to retrieve a heirarchy that looks like this

Team
    ChildTeams
Team
    Team
        ChildTeams

I've tried many approaches and seen many similar questions but none of them specifically helped me solve the problem. The latest attempt I tried went along these lines:

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});
}

I would pass the list of teams into the first ToGrouping(IEnumerable<Team>) and then subsequent returned groups into ToGrouping(IEnumerable<TeamGrouping>) but this is producing incorrect results.

Anyone have any advice or ideas?

解决方案

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];
}

这篇关于LINQ递归查询返回分层组集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆