C# Linq双列表关联过滤:按A类Name筛选B类列表
解决Linq筛选关联对象的问题
嘿,这个需求其实用Linq很容易实现,我给你分享几种常用的写法,你可以根据自己的数据规模和代码风格来选:
1. 直观但适合小数据量的写法:Where + Any
这种写法最直接,一眼就能看懂逻辑,但如果你的listA和listB数据量比较大,性能会稍差——因为每个B对象都会遍历一遍listA找匹配项:
public List<B> Filter(List<A> listA, List<B> listB, string name) { return listB.Where(b => listA.Any(a => a.AID == b.AID && a.Name == name)).ToList(); }
2. 高性能优先:先提取匹配的AID集合
如果数据量较大,推荐先把符合条件的A的ID提取到HashSet里(查找速度是O(1)),再筛选B,这样只需要遍历listA一次:
public List<B> Filter(List<A> listA, List<B> listB, string name) { // 先筛选出Name匹配的所有A的ID,存到HashSet提升查找效率 var matchingAIds = listA .Where(a => a.Name == name) .Select(a => a.AID) .ToHashSet(); // 直接匹配B的AID是否在集合中 return listB.Where(b => matchingAIds.Contains(b.AID)).ToList(); }
3. 类数据库关联风格:Linq Join方法
如果你习惯数据库的关联查询思路,用Join写法会更贴合这种思维,内部同样做了性能优化,和第二种方案效率差不多:
public List<B> Filter(List<A> listA, List<B> listB, string name) { return listB.Join( listA.Where(a => a.Name == name), // 关联的右集合:已筛选出符合Name的A b => b.AID, // B的关联字段 a => a.AID, // A的关联字段 (b, a) => b // 最终返回B对象 ).ToList(); }
额外提示
- 如果需要忽略大小写匹配Name,可以把
a.Name == name改成string.Equals(a.Name, name, StringComparison.OrdinalIgnoreCase),根据业务需求选择合适的字符串比较规则。 - 如果
name可能为null或空字符串,记得提前做参数校验,避免意外的空引用问题。
内容的提问来源于stack exchange,提问作者DirtyNative
相关产品推荐
相关产品推荐

