繁体   English   中英

如何重写曾经在 .NET Core 2.0 中工作但在 3.0 中不起作用的 EF LINQ 查询?

[英]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 可枚举转换为单个可枚举的原始值,然后使用ContainsAny在其上“调用”它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM