EF Core 7如何将两列UserId合并为去重单列表?
解决方案
你的问题出在EF Core无法将new[] { p.UserId1, p.UserId2 }这种数组构造的LINQ表达式翻译成SQL,导致必须客户端评估。要在数据库端高效完成合并去重,换用UNION的写法即可,无需先加载数据到内存。
方法一:拆分查询后用Union合并
// 先分别筛选出两列的用户ID,再用Union自动去重 var userId1Query = _dbContext.MyTable.Where(p => ...).Select(p => p.UserId1); var userId2Query = _dbContext.MyTable.Where(p => ...).Select(p => p.UserId2); var distinctUserIds = await userId1Query.Union(userId2Query).ToListAsync();
Union会被EF Core翻译成SQL的UNION语句,直接在数据库端完成两列数据的合并和去重,性能远优于客户端评估。
方法二:复用筛选条件简化代码
如果不想重复写Where筛选逻辑,可以先定义筛选后的子查询,再分别取两列合并:
var filteredTable = _dbContext.MyTable.Where(p => ...); var distinctUserIds = await filteredTable.Select(p => p.UserId1) .Union(filteredTable.Select(p => p.UserId2)) .ToListAsync();
这种写法和方法一效果一致,只是更简洁,EF Core会自动优化生成对应的SQL。
为什么原代码报错?
EF Core对数组构造+SelectMany的组合没有对应的SQL翻译逻辑,因为SQL中没有直接的数组展开操作,所以只能强制客户端评估(即先把筛选后的所有行加载到内存再处理),但这种方式在数据量大时性能很差。
内容的提问来源于stack exchange,提问作者VladL
相关产品推荐
相关产品推荐

