Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get child record using Linq

This is my first time to hear about LINQ and I have no idea about it. Please be gentle on me.

I have this set of data.

+---------+--------+---------------+
| 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 |               |
+---------+--------+---------------+

What I need to do is to write a method that returns a list of NodeID. example,

List<int> dependentNode = GetChildNode(1); // int ParentNode

My expected results are NodeIDs: 2 and 11.

NodeID = 2 is included because there is a RadioID = R7 that is connected to RadioID = R0 which belongs to NodeID = 1.

NodeID = 11 is also included because RadioID = R11 is connected to Radio = R9 which belongs to NodeID = 2 (which is also connected to NodeID = 1).

I lookup this article but I always get StackOverFlowException

  • Rendering a hierarchy using LINQ

Here's the full code:

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

}

You can suggest if there is much better way to do it. Sorry Newbie here.

like image 571
Skinny Pipes Avatar asked Nov 03 '22 22:11

Skinny Pipes


1 Answers

If you are newbie dont be too clever with recursion and lambdas.

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

UPDATE 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();
}
like image 167
Vitaly Bashilov Avatar answered Nov 11 '22 04:11

Vitaly Bashilov