EF Core 3.1报LINQ表达式无法翻译错误,如何不使用客户端求值解决
问题原因
你原先的写法无法翻译是因为EF Core 3.x不支持将内存集合SelectedIds的筛选逻辑和数据库查询返回的行属性i.SentDate进行嵌套绑定,EF无法将这类混合内存集合运算和数据库字段运算的逻辑下推为SQL。
可行解决方案
方案1:调整查询逻辑(适合SelectedIds数据量不大的场景)
将嵌套的Select+Contains改为两层Any直接做属性比对,该写法可被EF Core 3.1直接翻译为SQL的EXISTS子句,完全走服务端求值:
var list = _context.Table1 .Include(i => i.ListofGroupIds) .Where(i => i.ListofGroupIds.Any(g => SelectedIds.Any(s => s.Id == g.GroupId && s.CreatedDate <= i.SentDate) ) );
如果还是报错,可以提前把SelectedIds转为数组再传入查询:var selectedArray = SelectedIds.ToArray();,之后用selectedArray代替上面的SelectedIds即可。
方案2:临时表关联查询(适合SelectedIds数据量大的场景)
如果SelectedIds条目超过1000条,方案1生成的SQL语句会过长影响性能,此时可以用临时表方案:
- 在数据库中创建临时表
TempSelectedIds,包含Id、CreatedDate两个和SelectedIds对应的字段 - 提前将
SelectedIds批量插入到该临时表 - 编写关联查询即可,完全走SQL服务端运算,性能最优:
var list = _context.Table1 .Include(i => i.ListofGroupIds) .Where(i => i.ListofGroupIds.Any(g => _context.TempSelectedIds.Any(t => t.Id == g.GroupId && t.CreatedDate <= i.SentDate) ) );
内容的提问来源于stack exchange,提问作者user3501613
相关产品推荐
相关产品推荐

