.NET 6 EF Core嵌套All/Any的LINQ查询无法翻译怎么解决?
问题解答
关于Where()中使用All()/Any()的说明
可以在EF Core的Where()方法中使用All()或Any()方法,但存在限制:只有当All()/Any()操作的对象是EF Core映射的数据库实体导航属性集合时,才能被正常翻译为EXISTS类的SQL子查询。你当前代码中All()操作的是本地内存集合_searchList,EF Core没有内置对应的SQL翻译逻辑,因此会抛出表达式无法翻译的错误。
最优解决方案:动态拼接查询条件
你的需求是筛选出Name字段匹配_searchList中所有模糊规则的记录,等价于对每个搜索规则拼接AND条件的Like查询,可通过循环拼接Where()实现,写法简单且可以完全被翻译为SQL,全程在数据库端执行,性能最优:
List<string> _searchList = new() {"%a%", "%b%"}; var _query = _DbContext.batches.Where(tblHeader => tblHeader.isDeleted != true); // 逐个添加Like条件,等价于原All()的逻辑:所有搜索规则都匹配 foreach (var pattern in _searchList) { _query = _query.Where(x => EF.Functions.Like(x.Name, pattern)); } var _results = await _query.ToListAsync();
如果你的需求是匹配_searchList中任意一个模糊规则(对应原逻辑换为Any()),则需要通过表达式树动态拼接OR条件,可使用第三方库的PredicateBuilder工具实现,或者手动构建表达式树。
不推荐的兜底方案:客户端评估
你也可以按照错误提示显式切换到客户端评估,但该方案会将所有符合isDeleted != true的记录全部加载到内存后再执行过滤,数据量较大时性能极差,仅建议在数据量极小的场景下使用:
List<string> _searchList = new() {"%a%", "%b%"}; var _results = await _DbContext.batches .Where(tblHeader => tblHeader.isDeleted != true) .AsAsyncEnumerable() .Where(x => _searchList.All(y => EF.Functions.Like(x.Name, y))) .ToListAsync();
内容的提问来源于stack exchange,提问作者wittabeast
相关产品推荐
相关产品推荐

