如何使用LINQ查询嵌套层级中指定Id的MyType对象?
解决方案:查询两层(或多层)结构中的MyType对象
因为你的数据明确是两层结构,我们可以用两种方式实现需求:一种是针对两层的高效写法,另一种是兼容任意层级的通用递归写法,你可以根据情况选择。
1. 针对两层结构的快速实现
既然只有父级和子级两层,我们可以直接把父级集合和所有子级集合合并成一个扁平集合,再进行查询,这样代码简洁且高效:
// 假设你的父级集合是IEnumerable<MyType> collection string targetId = "2"; // 要查询的目标ID var result = collection // 合并父级集合和所有子级集合(处理Children为null的情况) .Concat(collection.SelectMany(parent => parent.Children ?? Enumerable.Empty<MyType>())) .FirstOrDefault(item => item.Id == targetId);
代码说明:
SelectMany(parent => parent.Children ?? Enumerable.Empty<MyType>()):把所有父级的子级扁平化成一个单独的集合,用?? Enumerable.Empty<MyType>()避免Children为null时抛出异常。Concat:将父级集合和子级集合合并成一个完整的扁平集合。- 最后用
FirstOrDefault根据Id匹配目标对象,不管它是父级还是子级。
2. 兼容任意层级的通用递归方案
如果以后你的数据结构可能扩展到多层,推荐用递归遍历所有节点的方式,这种写法更通用:
首先可以写一个扩展方法来遍历所有层级的节点:
public static class MyTypeExtensions { public static IEnumerable<MyType> FlattenAllNodes(this IEnumerable<MyType> collection) { foreach (var parent in collection) { // 返回当前父级节点 yield return parent; // 如果有子级,递归遍历子级的所有节点 if (parent.Children != null) { foreach (var child in parent.Children.FlattenAllNodes()) { yield return child; } } } } }
然后使用这个扩展方法查询:
string targetId = "5"; var result = collection.FlattenAllNodes().FirstOrDefault(item => item.Id == targetId);
效果验证
用你给出的示例数据测试:
- 查询
Id="1"会返回第一个父级对象 - 查询
Id="3"会返回第一个父级的第二个子对象 - 查询
Id="6"会返回第二个父级的第二个子对象
完全满足你要查询父级或子级对象的需求!
内容的提问来源于stack exchange,提问作者Yahya Hussein
相关产品推荐
相关产品推荐

