我需要获取一个嵌套集合的节点,通过它深入了解linq。
这是嵌套类:
public class Group
{
public int Id { get; set; }
public string Description { get; set; }
public int ParentId { get; set; }
public List<Group> Groups { get; set; }
}
此类的每个实例都可以在Groups方法中包含多个实例,依此类推。每个实例都通过ParentId属性进行链接。
我需要有一个Group类的实例来检索他的父亲。我试过这个:
var parent = _repositoryGroups
.Where(g => g.Id == [my Group instance].ParentId)
.SelectMany(g => g.Groups)
.FirstOrDefault()
我不知道为什么,但并不总是找到父实例,它从第二层开始寻找(但这不是一个真正的问题)。
通过这个嵌套类的所有深层找到元素的最佳方法是什么?
由于
答案 0 :(得分:1)
现在听起来你想让所有孩子递归某个群体。
所以你可以:
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;
}
}
}
}
如果您只想获得某个组的父母:
private Group GetParent(Group child)
{
_repositoryGroups.Where(g => g.Id == child.ParentId).FirstOrDefault();
}
如果您需要获得某个组的超级父母(父母的父母的父母):
private Group GetSuperParent(Group child)
{
parent = GetParent(child);
while (parent != null)
{
child = parent;
parent = GetParent(child);
}
return child;
}
最重要的是,我建议如果你能做到这一点,请保留对父母的引用,而不是它的ID。如果没有父亲,请将其设为null。省去了很多麻烦。很多。
答案 1 :(得分:0)
如果你想上你的结构并找到父母的最后一位父母,你可以使用这段代码:
var group = [my Group instance];
while(group.ParentId > 0)
{
group = _repositoryGroups.First(g => g.Id == group.ParentId);
}
这假设您的ID高于零,并且id> 0将始终具有有效的父级。
答案 2 :(得分:0)
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;
}
如果您使用linq有更好的解决方案,请告诉我。