Darion Badlydone
Darion Badlydone

Reputation: 947

Linq infinite nested query

I need to get a node of a nested collection looking through It's deep with linq.

This is the nested class:

public class Group
{

    public int Id { get; set; }

    public string Description { get; set; }

    public int ParentId { get; set; }

    public List<Group> Groups { get; set; }

}

Each instance of this class can have multiple instances inside the Groups method and so on. Each instance is linked through the ParentId property.

I need, having an instance of Group class, retrieve his father. I tried with this:

var parent = _repositoryGroups
.Where(g => g.Id == [my Group instance].ParentId)
.SelectMany(g => g.Groups)
.FirstOrDefault()

I don't know why, but not always it find the father instance and It starts looking from the second level (but this is not a real problem).

What's the best way to find the element through all the deep of this nested class?

Thanks

Upvotes: 0

Views: 1321

Answers (3)

Darion Badlydone
Darion Badlydone

Reputation: 947

Sorry guys, maybe I didn't explain my question very well. I've developed this solution inspiring to yours answers:

private static Group GetGroupFather(IEnumerable<Group> groups, Group child)

{

    foreach (var group in groups)
{

    // try to nested search
    var result = GetGroupFather(group.Groups, child);

    if (result != null) return result;

    // check in the current level
    if (group.Id == child.ParentId)

        return group;

}

return null;

}

If you have a better solution using linq, please let me know.

Upvotes: 0

Schiavini
Schiavini

Reputation: 2939

If you want to go up your structure and find the last parent of the parents, you can use this piece of code:

var group = [my Group instance];

while(group.ParentId > 0)
{
    group = _repositoryGroups.First(g => g.Id == group.ParentId);
}

This assumes your IDs are higher than zero, and that an id>0 will always have a valid parent.

Upvotes: 0

YoryeNathan
YoryeNathan

Reputation: 14512

It now sounds like you want to get all childs recursively of a certain group.

So you can have:

private IEnumerable<Group> EnumerateChildren(Group parent)
{
    if (parent.Groups != null)
    {
        foreach (var g in parent.Groups)
        {
            yield return g;

            foreach (var sub in EnumerateChildren(g))
            {
                yield return sub;
            }
        }
    }
}

If you just want to get the parent of a certain group:

private Group GetParent(Group child)
{
    _repositoryGroups.Where(g => g.Id == child.ParentId).FirstOrDefault();
}

And if you need to get the super-parent of a certain group (parent of parent of parent of...):

private Group GetSuperParent(Group child)
{
    parent = GetParent(child);

    while (parent != null)
    {
        child = parent;
        parent = GetParent(child);
    }

    return child;
}

Above it all, I recommend that if you can do that, hold a reference to the parent instead of it's Id. Have it null if it has no father. Saves a lot of trouble. A lot.

Upvotes: 2

Related Questions