LINQ表达式无法转换,如何规避客户端评估且不调用ToList?
问题
数据量过大无法调用ToList()触发客户端评估,现需修改以下C#查询以避免该问题:
return new AuthRight<ABCContainerDto<List<QTypeDto>>> { Item = new ABCContainerDto<List<QTypeDto>> { Proj = _mapperService.MapToDto<Proj, EstimationDto>(proj), Data = _context.Quant .Where(x => x.EstimationID.Equals(estimation.ID)) .DistinctBy(x => x.QuantTypeID) .Select(x => x.QuantType.MapToDto()) .OrderBy(x => x.Code) .ToList() }, AccessLevel = projectAccessLevel.MapToDto() };
当前报错:
LINQ表达式'DbSet
().Where(x => x.EstimationID.Equals(__estimation_ID_0)).DistinctBy(x => x.QuantTypeID)'无法被翻译。请将查询重写为可翻译的形式,或通过插入对'AsEnumerable'、'AsAsyncEnumerable'、'ToList'或'ToListAsync'的调用显式切换到客户端评估。
因数据量限制无法使用客户端评估方法,需找到可行的规避方案。
解决方案
方法1:用GroupBy替代DistinctBy
EF Core无法直接将DistinctBy翻译为SQL,可通过GroupBy按QuantTypeID分组,再取每组第一条数据实现去重逻辑:
Data = _context.Quant .Where(x => x.EstimationID == estimation.ID) .GroupBy(x => x.QuantTypeID) .Select(g => g.First().QuantType) // 取每组第一个关联的QuantType .Select(qt => qt.MapToDto()) .OrderBy(x => x.Code) .ToList()
方法2:直接查询QuantType表关联过滤
如果业务逻辑允许,直接从QuantType表出发,关联Quant表过滤符合条件的记录,避免在Quant表上处理冗余数据:
Data = _context.QuantType .Where(qt => _context.Quant.Any(q => q.EstimationID == estimation.ID && q.QuantTypeID == qt.ID)) .Select(qt => qt.MapToDto()) .OrderBy(x => x.Code) .ToList()
这种方式查询效率更高,因为直接针对目标表操作。
方法3:升级EF Core到7.0+版本
若项目使用EF Core 7.0或更高版本,DistinctBy已支持翻译为SQL(如PostgreSQL的DISTINCT ON、SQL Server的对应逻辑),此时原代码无需修改即可正常执行,直接实现数据库端评估。
内容的提问来源于stack exchange,提问作者Mannan Bahelim
相关产品推荐
相关产品推荐

