如何使用Linq基于指定三列获取去重的查询结果
问题修复与实现方案
首先你现有代码存在参数名笔误:Select 传入的遍历参数是 s,但后续给 user_name、created_by 赋值时用了之前Where里的参数 x,运行会直接报错,先修正这个问题。
以下分三种场景给出去重方案:
方案1:.NET 6 + / EF Core 3.0 + 环境(推荐,可直接翻译为SQL执行)
直接调用DistinctBy方法,指定要基于去重的三个字段即可,该方法会直接在数据库层面生成DISTINCT查询,不需要把全量数据拉到内存再处理,性能最优:
var result = db.SETUP_MASTER_LOGIN .Where(x => x.DELETED == false) .Select(s => new MasterLoginResp { resource_name = s.RESOURCE_NAME, user_name = s.USER_NAME, created_by = s.CREATED_BY }) .DistinctBy(x => new {x.resource_name, x.user_name, x.created_by}) .ToList();
方案2:低版本.NET/EF 环境(不支持DistinctBy)
用GroupBy模拟去重逻辑,同样可以在数据库端执行:
var result = db.SETUP_MASTER_LOGIN .Where(x => x.DELETED == false) .Select(s => new MasterLoginResp { resource_name = s.RESOURCE_NAME, user_name = s.USER_NAME, created_by = s.CREATED_BY }) .GroupBy(x => new {x.resource_name, x.user_name, x.created_by}) .Select(g => g.First()) .ToList();
方案3:已将数据拉到内存后需要去重
如果你的业务逻辑是先拿到全量列表再做去重,可自定义比较器传入Distinct()方法实现:
// 自定义比较器 public class MasterLoginRespComparer : IEqualityComparer<MasterLoginResp> { public bool Equals(MasterLoginResp x, MasterLoginResp y) { if (y == null) return false; return x.resource_name == y.resource_name && x.user_name == y.user_name && x.created_by == y.created_by; } public int GetHashCode(MasterLoginResp obj) { return HashCode.Combine(obj.resource_name, obj.user_name, obj.created_by); } } // 调用方式 var distinctResult = result.Distinct(new MasterLoginRespComparer()).ToList();
内容的提问来源于stack exchange,提问作者Daniiyal Baig
相关产品推荐
相关产品推荐

