You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用LINQ Where条件过滤列表中的多键匹配元素?

问题原因分析
  • a、b返回空列表:Student是引用类型,默认情况下Contains方法比较的是对象的引用地址,而非属性值。list和query中的Student都是不同实例,所以Contains始终返回false。
  • c返回4条数据:它的逻辑是判断Id存在于query的Id集合且RelatedId存在于query的RelatedId集合,这会筛选出所有Id为1/2且RelatedId为1/2的对象,也就是list中的全部元素,不符合预期的匹配逻辑。
解决方案

方案1:让Student类支持值相等性

实现IEquatable<Student>接口,重写相等比较逻辑,让Contains按属性值判断相等:

class Student : IEquatable<Student>
{
    public long Id { get; set; }
    public long RelatedId { get; set; }

    public bool Equals(Student other)
    {
        if (other is null) return false;
        return Id == other.Id && RelatedId == other.RelatedId;
    }

    public override bool Equals(object obj) => Equals(obj as Student);

    public override int GetHashCode() => HashCode.Combine(Id, RelatedId);
}

修改后,直接使用你原来的a写法就能得到正确结果:

var result = list.Where(x => query.Contains(x)).ToList();

方案2:使用LINQ的Any方法直接比较属性

不修改Student类,通过Any检查query中是否存在属性完全匹配的对象:

var result = list.Where(student => 
    query.Any(q => q.Id == student.Id && q.RelatedId == student.RelatedId)
).ToList();

方案3:借助匿名类型的默认值相等性

匿名类型的相等比较默认基于属性值,先将query转换为匿名类型的哈希集合,再进行匹配:

var queryAnon = query.Select(q => new { q.Id, q.RelatedId }).ToHashSet();
var result = list.Where(student => 
    queryAnon.Contains(new { student.Id, student.RelatedId })
).ToList();

内容的提问来源于stack exchange,提问作者Twoner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:39:19