如何使用Lambda表达式在C#中过滤深度嵌套对象?
如何用Lambda表达式在C#中过滤深度嵌套对象?
场景说明
现有嵌套对象结构如下:
Object A (A1) | Object B (B1) | Object C (C1) | Field = X | Object C (C2) | Field = Y | Object C (C3) | Field = Z | Object B (B2) | Object C (C1) | Field = X | Object B (B3) | Object C (C1) | Field = Y | Object B (B4) | Object C (C1) | Field = X | Object C (C2) | Field = Z | Object B (B5) | Object C (C1) | Field = Y | Object C (C2) | Field = Z Object A (A2) | Object B (B1) | Object C (C1) | Field = X | Object C (C2) | Field = Z | Object B (B2) | Object C (C1) | Field = Y
需要过滤出所有Field = X的Object C,同时保留原有的层级结构(即使B中没有符合条件的C,也要保留B对象;所有A对象都保留),预期结果如下:
Object A (A1) | Object B (B1) | Object C (C1) | Field = X | Object B (B2) | Object C (C1) | Field = X | Object B (B3) | Object B (B4) | Object C (C1) | Field = X | Object B (B5) Object A (A2) | Object B (B1) | Object C (C1) | Field = X | Object B (B2)
现有方案的问题
你目前找到的代码仅过滤出包含符合条件C的A对象,并未对嵌套的B、C集合进行筛选:
query.Where(a => a.ObjectB.Any(b => b.ObjectC.Any(c => c.Field == X)))
解决方案
要实现预期效果,需要通过Select投影来处理嵌套层级,保留所有A和B对象,仅过滤符合条件的C对象。代码如下:
// 假设你的实体类型为ObjectA、ObjectB、ObjectC var filteredData = query .Select(a => new ObjectA { // 复制ObjectA的其他属性,比如Id、Name等 Id = a.Id, Name = a.Name, // 处理ObjectB集合 ObjectB = a.ObjectB .Select(b => new ObjectB { // 复制ObjectB的其他属性 Id = b.Id, Name = b.Name, // 过滤ObjectC,仅保留Field等于X的项 ObjectC = b.ObjectC.Where(c => c.Field == "X").ToList() }) .ToList() }) .ToList();
说明
- 如果是内存集合(比如
List<ObjectA>),直接使用上述代码即可,无需额外处理。 - 如果是EF Core数据库查询,确保投影的类型是实体类型或匿名类型,EF Core支持这种嵌套的
Select和Where操作,能正确转换为SQL语句。 - 该方案会保留所有A对象和B对象,仅过滤掉不符合条件的C对象,完全匹配预期结果。
内容的提问来源于stack exchange,提问作者KP Code
相关产品推荐
相关产品推荐

