[英]How to rewrite EF LINQ query that used to work in .NET Core 2.0 but doesn't in 3.0?
我正在 .NET Core 3 中开发一个在线商店,遵循一些使用 .NET CORE 2 开发的教程。EF LINQ 在尝试执行此简单代码行后出错:
var stocksToUpdate = _context.Stock
.Where(x => request.Stocks
.Any(y => y.StockId == x.Id))
.ToList();
我收到以下错误:
InvalidOperationException:无法翻译 LINQ 表达式“
DbSet<Stock>.Where(s => __request_Stocks_0.Any(y => y.StockId == s.Id))
”。 以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。
老实说,我不知道如何以不同的方式编写该查询。 我已尝试按照建议替换 the.ToList() for.AsEnumerable,但它仍然出错,同样的错误。 有谁知道 .NET Core 3 的修复方法是什么? 提前致谢!
由于隐式客户端评估,它在 EF Core 2.x 中“工作”,该评估已在 3.0 中删除。 您可以通过在报告的有问题的运算符之前插入AsEnumerable()
来获得以前的行为 - 在您的情况下, Where
:
var stocksToUpdate = _context.Stock
.AsEnumerable()
.Where(x => request.Stocks.Any(y => y.StockId == x.Id))
.ToList();
但删除隐式客户端评估的主要原因是效率低下 - 检索整个表后,过滤发生在 memory 中。
因此,与其切换到客户评估,不如找到一个可翻译的结构。
您查询的问题是request.Stocks
是内存中的集合,EF Core 仅支持原始值的内存中 collections ,并且基本上Contains
方法。 所以以下工作
var stocksToUpdate = _context.Stock
.Where(x => request.Stocks.Select(y => y.StockId).Contains(x.Id))
.ToList();
你也可以使用
.Where(x => request.Stocks.Select(y => y.StockId).Any(y => y == x.Id))
这里的基本部分是将内存中的复杂 object 可枚举转换为单个可枚举的原始值,然后使用Contains
或Any
在其上“调用”它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.