使用Linq读取层次结构中的最后一个子项

本文关键字:最后一个 Linq 读取 层次结构 使用 | 更新日期: 2023-09-27 18:25:59

我有一个表,它包含下面的层次结构

ParentChildMap
{
    parent_id,
    child_id
}

另一个表包含Map 中每个成员的详细信息

Member_Details
{
    Member_Id,
    Member_Name
}

有时关系可以简单到Parent---->Child,有时关系可以有多个级别,如GG祖父-->G-GrandFather--->GrandFather-->Parent---->Child。

我想做的是列出某个家庭的所有孩子及其详细信息。

有人能帮我提供最有效的LINQ查询吗?

使用Linq读取层次结构中的最后一个子项

我意识到这个问题已经4年多没有答案了,但它似乎是一个有趣的问题。我认为以下方法应该适用于Linq查询。我基本上是在假设孩子不是父母。因此,如果这是真的,那么一个保留join的关系本身应该会产生所有不是父节点的节点。完成此操作后,详细信息的常规联接将与子节点的名称相匹配。以下是我的示例代码:

void Main()
{
    //    1
    //   2 3
    //  4    
    // 5 6
    // Child nodes are all those that are not parents: i.e.: 5, 6, 3
    var details = new[] {
        new Member_Details { Member_Id = 1, Member_Name = "Node 1" },
        new Member_Details { Member_Id = 2, Member_Name = "Node 2" },
        new Member_Details { Member_Id = 3, Member_Name = "Node 3" },
        new Member_Details { Member_Id = 4, Member_Name = "Node 4" },
        new Member_Details { Member_Id = 5, Member_Name = "Node 5" },
        new Member_Details { Member_Id = 6, Member_Name = "Node 6" },
    };
    var relationships = new[] {
        new ParentChildMap { parent_id = 1, child_id = 2 },
        new ParentChildMap { parent_id = 1, child_id = 3 },
        new ParentChildMap { parent_id = 2, child_id = 4 },
        new ParentChildMap { parent_id = 4, child_id = 5 },
        new ParentChildMap { parent_id = 4, child_id = 6 }
    };
    var children = relationships
        .GroupJoin(relationships, r1 => r1.child_id, r2 => r2.parent_id, (r1, r2) => r2
            .Select(x => new { Inner = r1.child_id, Outer = x.child_id})
            .DefaultIfEmpty(new { Inner = r1.child_id, Outer = 0 }))
        .SelectMany(x => x)
        .Where(x => x.Outer == 0)
        .Join(details, r => r.Inner, d => d.Member_Id, (r, d) => new {Id = r.Inner, Name = d.Member_Name});
    foreach (var child in children)
    {
        Console.WriteLine($"ID: {child.Id}, Name: {child.Name}");
    }
}
public class ParentChildMap
{
    public int parent_id;
    public int child_id;
}
public class Member_Details
{
    public int Member_Id;
    public string Member_Name;
}