Reputation: 947
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
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
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
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