如何用LINQ实现类似SQL Except的表对比:筛选Table1独有的TypeId+VersionId组合
解决方法:Except 还是 Where?
针对你的需求,两种方法都能实现,下面分别给出示例和适用场景:
方法一:使用 .Except()
你已经提取了Table2的(TypeId, VersionId)组合,只需对Table1做相同的匿名类型投影,再调用Except就能直接得到两个集合的差集:
var result1 = this.Table2 .Select(k => new { k.TypeId, k.VersionId }) .ToArray(); var finalResult = this.Table1 .Select(t => new { t.TypeId, t.VersionId }) .Except(result1) .ToArray();
注意:匿名类型的属性名称、数据类型必须完全一致,LINQ才会自动按属性值做相等比较。这种方法代码简洁,逻辑直观,适合只需要获取目标字段差集的场景。
方法二:使用 .Where()
如果需要先保留Table1的完整记录,或者想更直白地写过滤逻辑,可以用Where配合!Any()判断当前记录的组合是否不在Table2的集合中:
var result1 = this.Table2 .Select(k => new { k.TypeId, k.VersionId }) .ToArray(); var finalResult = this.Table1 .Where(t => !result1.Any(r => r.TypeId == t.TypeId && r.VersionId == t.VersionId)) .Select(t => new { t.TypeId, t.VersionId }) .ToArray();
这种方法灵活性更高,比如你可以在Select之前对Table1的其他字段做处理。
额外优化(ORM场景)
如果是用EF Core这类ORM,尽量不要提前调用.ToArray()把数据拉到内存,直接用IQueryable操作会让数据库层面执行查询,性能更优:
var finalResult = this.Table1 .Select(t => new { t.TypeId, t.VersionId }) .Except(this.Table2.Select(k => new { k.TypeId, k.VersionId })) .ToArray();
内容的提问来源于stack exchange,提问作者Sebastián Rubina
相关产品推荐
相关产品推荐

