如何用LINQ对三层嵌套列表内的metaData属性做全层级精准过滤
三层嵌套列表LINQ过滤实现方案
原有代码的问题
你之前写的逻辑仅通过Any()判断外层用户是否存在匹配项,本质是只做了“有无匹配”的存在性校验,没有对中间层、最内层的集合内容做过滤重构,因此不匹配的ResourceTypeUserVm、ResourceUserVm条目会一直保留,无法得到正确的精简结构。
核心实现逻辑
每一层嵌套集合都要执行两步操作:
- 先对当前层包含的子集合做匹配过滤,只保留符合条件的子条目
- 再将过滤后子集合为空的当前层条目直接移除,避免出现层级残留的无效数据
完整LINQ实现代码
// 提前统一关键词大小写,避免匹配偏差 var keyword = value?.ToLower() ?? string.Empty; var filteredUsers = users // 重构每个User对象的嵌套结构 .Select(user => new UserUserVm { UserName = user.UserName, // 重构当前User下的ResourceTypeUserVm集合 ResourceTypeUserVms = user.ResourceTypeUserVms .Select(resourceType => new ResourceTypeUserVm { Name = resourceType.Name, Description = resourceType.Description, // 过滤最内层ResourceUserVm,仅保留metaData匹配的条目 ResourceUserVms = resourceType.ResourceUserVms .Where(resource => !string.IsNullOrEmpty(resource.MetaData) && resource.MetaData.ToLower().Contains(keyword) ) .ToList() }) // 移除没有任何匹配ResourceUserVm的ResourceTypeUserVm条目 .Where(resourceType => resourceType.ResourceUserVms.Any()) .ToList() }) // 移除没有任何有效ResourceTypeUserVm的User条目 .Where(user => user.ResourceTypeUserVms.Any()) .ToList();
实现效果说明
- 完全匹配预期筛选结果:仅保留存在匹配项的用户,保留对应用户下存在匹配条目的ResourceTypeUserVm,每个ResourceTypeUserVm下仅保留metaData命中的ResourceUserVm
- 规避了原多层foreach实现的重复条目问题:原写法每检测到一个匹配的ResourceUserVm就会重新构造完整的User、ResourceTypeUserVm对象,当同一个ResourceType下存在多个匹配项时会生成重复的层级结构,上述LINQ写法会将同一层级下的所有匹配项聚合到同一个集合中,结构完全符合预期
- 加入了空值校验,避免MetaData为null时抛出空引用异常,鲁棒性更强
内容的提问来源于stack exchange,提问作者Snoopy111
相关产品推荐
相关产品推荐

