我有一个如下所示的模型:
public class MyType{
public string Id {get;set;}
public string Name{get;set;}
public List<MyType> Children{get;set;}
}
Run Code Online (Sandbox Code Playgroud)
在我的数据中,我只有两个级别的数据,这意味着我的对象将如下所示:
{
MyType{"1","firstParent",
{
MyType{"2","firstChild",null},
MyType{"3","secondChild",null}}
},
MyType{"4","secondParent",
{
MyType{"5","firstChild",null},
MyType{"6","secondChild",null}}
}
}
Run Code Online (Sandbox Code Playgroud)
如何查询MyType对象的特定Id,它可能是父或子?
以下将仅返回父母.
collection.FirstOrDefault(c => c.id==id)
Run Code Online (Sandbox Code Playgroud)
您可以使用Any递归本地函数来查找任何级别的对象(您的数据结构似乎表明更深层次是可能的)
bool hasIdOrChildren(MyType t, string localId)
{
return t.Id == localId || (t.Children != null && t.Children.Any(o => hasIdOrChildren(o, localId)));
}
collection.FirstOrDefault(c => hasIdOrChildren(c, id));
Run Code Online (Sandbox Code Playgroud)
或者使用pre C#7语法:
Func<MyType, string, bool> hasIdOrChildren = null;
hasIdOrChildren = (MyType t, string localId) =>
{
return t.Id == localId || (t.Children != null && t.Children.Any(o => hasIdOrChildren(o, localId)));
};
collection.FirstOrDefault(c => hasIdOrChildren(c, id));
Run Code Online (Sandbox Code Playgroud)
如果您只对一个级别感兴趣,可以放弃隐遁:
collection.FirstOrDefault(c => c.Id == id || (c.Children != null && c.Children.Any(o => o.Id == id)));
Run Code Online (Sandbox Code Playgroud)
编辑
上面的代码给出了父代如果任何子代码具有id,你也可以使用SelectMany递归函数展平整个树结构:
IEnumerable<MyType> flattenTree(MyType t)
{
if(t.Children == null)
{
return new[] { t };
}
return new[] { t }
.Concat(t.Children.SelectMany(flattenTree));
};
collection
.SelectMany(flattenTree)
.FirstOrDefault(c => c.Id == id);
Run Code Online (Sandbox Code Playgroud)
此方法可用于需要展平树的任何类型的处理.