Entity Framework 3.0 Contains 无法像在 EF Core 2.2 中那样在 SQL 中进行转换 [英] Entity Framework 3.0 Contains cannot be translated in SQL as it was in EF Core 2.2
问题描述
我正在尝试将 Web API 从 .NET Core 2.2 迁移到 .NET Core 3.0,但我偶然发现了以下内容:
I am trying to migrate a Web API from .NET Core 2.2 to .NET Core 3.0 and I have stumbled across the following:
public Dictionary<int, Tag> GetTagMap(IList<int> tagIds = null)
{
var tags = context.Tag.AsNoTracking();
if (tagIds != null)
tags = tags.Where(t => tagIds.Contains(t.TagId));
return tags
.ToList() // explicit client evaluation in 3.0
.ToDictionary(t => t.TagId, t => t);
}
这用来生成一个类似于这个的SQL语句:
This used to generate a SQL statement similar to this one:
SELECT TagId, Name FROM Tag WHERE TagId IN (1, 2, 3)
这对于正确索引的列和少量 IN
值非常有效.
which worked very well for correctly indexed column and a small number of IN
values.
现在我收到以下错误提示 List<>.Contains
翻译不再受支持:
Now I receive the following error suggesting that List<>.Contains
translation is not supported anymore:
System.InvalidOperationException: 'LINQ 表达式'Where(来源:DbSet,谓词:(t) =>(未处理的参数:__tagIds_0).Contains(t.TagId))' 无法翻译.要么以可翻译的形式重写查询,要么切换到通过插入对任何一个的调用来显式地进行客户端评估AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync().看客户端与服务器评估 - EF Core 了解更多信息.'
System.InvalidOperationException: 'The LINQ expression 'Where( source: DbSet, predicate: (t) => (Unhandled parameter: __tagIds_0).Contains(t.TagId))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See Client vs. Server Evaluation - EF Core for more information.'
这表明 LINQ 查询不再在客户端上进行评估 破坏性更改,但 AFAIK Contains
未在客户端上进行评估客户.
This suggests the LINQ queries are no longer evaluated on the client breaking change, but AFAIK Contains
was not evaluated on the client.
推荐答案
这是一个 3.0 错误,由 #17342:包含在通用 IList/HashSet/ImmutableHashSet 上将抛出异常.
It's a 3.0 bug, tracked by #17342: Contains on generic IList/HashSet/ImmutableHashSet will throw exception.
已在 3.1 中修复.解决方法(如果您迫不及待的话)是强制使用 Enumerable.Contains
,例如
Already fixed in 3.1. The workaround (if you can't wait) is to force the usage of Enumerable.Contains
, for instance
t => tagIds.AsEnumerable().Contains(t.TagId)
或者改变变量的类型.
这篇关于Entity Framework 3.0 Contains 无法像在 EF Core 2.2 中那样在 SQL 中进行转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!