C#复杂Linq查询:筛选ID匹配的父对象及对应子对象
解决两种父对象筛选需求的实现方案
咱先把已知的类结构再明确下,方便对照代码:
public class Parent { public string Id{get;set;} public string Name{get;set;} public List<Child> Children{get;set;} } public class Child{ public string Id{get;set;} public string Name{get;set;} }
接下来分两种需求逐一实现:
一、筛选ID在Ids中的父对象,保留所有子对象
这个需求比较直接,只需要过滤父对象的ID是否在目标列表里就行,子对象完全保留:
// 第一种结果:父ID匹配,保留所有子对象 List<Parent> result1 = parents .Where(p => Ids.Contains(p.Id)) .ToList();
如果Ids的元素数量较多,推荐先转成HashSet来提升Contains的查询性能:
var idHashSet = new HashSet<string>(Ids); List<Parent> result1 = parents .Where(p => idHashSet.Contains(p.Id)) .ToList();
二、筛选包含ID匹配子对象的父对象,仅保留匹配的子对象
这个需求需要两步:先找出至少有一个子对象ID在Ids里的父对象,然后重新构造父对象实例,只保留其中ID匹配的子对象(避免修改原列表的父对象数据):
// 第二种结果:包含匹配子对象的父,仅保留匹配的子 var idHashSet = new HashSet<string>(Ids); // 同样用HashSet优化性能 List<Parent> result2 = parents .Where(p => p.Children?.Any(c => idHashSet.Contains(c.Id)) == true) // 先过滤有匹配子的父 .Select(p => new Parent { Id = p.Id, Name = p.Name, Children = p.Children?.Where(c => idHashSet.Contains(c.Id)).ToList() ?? new List<Child>() // 只保留匹配的子,处理Children为null的情况 }) .ToList();
补充说明
- 代码里加了
?.和??空值判断,是为了避免Children为null时出现空引用异常,让代码更健壮。 - 选择重新构造
Parent对象而不是直接修改原对象的Children属性,是为了防止污染原始的parents列表数据,保持数据的纯净性。如果业务允许修改原对象,也可以直接在Where后修改Children,但不推荐这么做哦。
内容的提问来源于stack exchange,提问作者Yahya Hussein
相关产品推荐
相关产品推荐

