使用Linq获取子记录

Ski*_*pes 5 c# linq linq-to-sql

这是我第一次听到LINQ,我也不知道.请温柔我.

我有这组数据.

+---------+--------+---------------+
| RadioID | NodeID | SourceRadioID |
+---------+--------+---------------+
| R0      |      1 |               |
| R1      |      1 |               |
| R2      |      1 |               |
| R3      |      1 |               |
| R4      |      1 |               |
| R5      |      2 |               |
| R6      |      2 |               |
| R7      |      2 | R0            |
| R8      |      2 |               |
| R9      |      2 |               |
| R10     |     11 |               |
| R11     |     11 | R9            |
| R12     |     11 |               |
| R13     |     11 |               |
+---------+--------+---------------+
Run Code Online (Sandbox Code Playgroud)

我需要做的是编写一个返回列表的方法NodeID.例,

List<int> dependentNode = GetChildNode(1); // int ParentNode
Run Code Online (Sandbox Code Playgroud)

我的预期结果是NodeID : 2 and 11.

NodeID = 2被包括,因为有一个RadioID = R7连接到RadioID = R0属于NodeID = 1.

NodeID = 11也包括因为RadioID = R11连接Radio = R9属于NodeID = 2(也连接到NodeID = 1).

我查了这篇文章,但我总是得到 StackOverFlowException

这是完整的代码:

public class RadioEntity
{
    public string RadioID { get; set; }
    public int NodeID { get; set; }
    public string SourceRadioID { get; set; }
}

public class SampleDemo
{
    public void SampleMethod()
    {

        Func<int, int,List<int>> GetChildNode = null;
        GetChildNode = (x, y) =>
            {
                return (from _x in GetRadio()
                        where (GetRadio().Where(i => i.NodeID == x).Select(i => i.RadioID)).Contains(_x.RadioID)
                        from _y in new[] { _x.NodeID }.Union(GetChildNode(_x.NodeID, y + 1))
                        select _y).ToList<int>();
            };

        var _res = GetChildNode(1, 0);

    }

    public List<RadioEntity> GetRadio()
    {
        List<RadioEntity> _returnVal = new List<RadioEntity>();
        _returnVal.Add(new RadioEntity() { RadioID = "R0", NodeID = 1, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R1", NodeID = 1, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R2", NodeID = 1, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R3", NodeID = 1, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R4", NodeID = 1, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R5", NodeID = 2, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R6", NodeID = 2, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R7", NodeID = 2, SourceRadioID = "R0" });
        _returnVal.Add(new RadioEntity() { RadioID = "R8", NodeID = 2, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R9", NodeID = 2, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R10", NodeID = 11, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R11", NodeID = 11, SourceRadioID = "R9" });
        _returnVal.Add(new RadioEntity() { RadioID = "R12", NodeID = 11, SourceRadioID = "" });
        _returnVal.Add(new RadioEntity() { RadioID = "R13", NodeID = 11, SourceRadioID = "" });

        return _returnVal;
    }

}
Run Code Online (Sandbox Code Playgroud)

你可以建议是否有更好的方法来做到这一点.抱歉新手在这里.

小智 2

如果您是新手,请不要对递归和 lambda 太聪明。

    public List<int> GetChildren(int id)
    {
        var nodes = GetRadio();
        var parent = nodes.Single(n => n.NodeID == id);
        var children = nodes.Where(n => n.SourceRadioID == parent.RadioID).Select(n => n.NodeID);

        return children.Union(children.SelectMany(GetChildren)).ToList();
    }
Run Code Online (Sandbox Code Playgroud)

更新1

public List<int> GetChildren(int id)
{
    IEnumerable<RadioEntity> parent = GetRadio().Where(x => x.NodeID == id);
    IEnumerable<int> children = (
                                    from r in GetRadio()
                                    where parent.Select(x=>x.RadioID)
                                                .Contains(r.SourceRadioID)
                                    select r
                                ).Select(n => n.NodeID);

    return children.Union(children.SelectMany(GetChildren)).ToList();
}
Run Code Online (Sandbox Code Playgroud)