.Net Core 3.1 实现商品动态多复选框筛选时报查询无法翻译错误如何解决
问题原因
EF Core 3.1默认禁用了隐式客户端评估,你代码中_modelAttributeValueRepository.GetFind(x => list.Any(j => j.Search == x.Value && j.AttributeId == x.AttributeId))这行的查询条件里,list是你拆分后生成的内存自定义对象集合,EF Core无法将内存集合的Any匹配逻辑翻译成SQL语句,因此抛出无法翻译的错误。
修复方案
方案1:使用复合键匹配(推荐,全数据库端查询,性能最优)
把拆分后的筛选条件转换成字符串形式的复合键列表,EF Core可以识别这种格式的Contains操作并翻译成SQL,不会触发客户端评估:
public async Task<IActionResult> Index(SearchOption searchOption, int pageSize = 10) { var query = _productRepo.Query() .Include(x => x.AttributeValues) .Where(x => x.InActive == true); if (!string.IsNullOrWhiteSpace(searchOption.filter)) { // 拆分筛选条件,生成 AttributeId_Value 格式的复合键列表 var filterKeys = searchOption.filter.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries) .Select(item => { var subItems = item.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); return $"{subItems[1]}_{subItems[0]}"; }).ToList(); if (filterKeys.Any()) { // 此处的Contains可以被EF Core正常翻译成SQL的IN操作 var productIds = _modelAttributeValueRepository .GetFind(x => filterKeys.Contains($"{x.AttributeId}_{x.Value}")) .Select(x => x.ProductId) .ToList(); query = query.Where(x => productIds.Contains(x.ProductId)); } } // 原方法为异步方法,使用异步查询避免线程阻塞 return View(await query.ToListAsync()); }
注意:复合键拼接使用的分隔符要保证不会出现在属性值或者属性ID中,避免出现意外匹配错误。
方案2:显式客户端评估(仅适合小数据量场景)
如果你确认属性值表的数据量非常小,可以显式把查询拉到内存后再执行过滤,不过数据量大时性能会大幅下降:
// 仅需要修改属性值查询部分,通过AsEnumerable()触发内存计算 var attr = _modelAttributeValueRepository .GetFind(x => true) .AsEnumerable() .Where(x => list.Any(j => j.Search == x.Value && j.AttributeId == x.AttributeId)) .Select(x => x.ProductId) .ToList();
内容的提问来源于stack exchange,提问作者İbrahim
相关产品推荐
相关产品推荐

