实体框架3.0包含无法像在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).包含(t.TagId))'无法翻译.以可以翻译的形式重写查询,或切换到 通过插入对其中任何一个的调用来显式地进行客户评估 AsEnumerable(),AsAsyncEnumerable(),ToList()或ToListAsync().看 客户端与服务器评估-EF核心,以获取更多信息.'
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)
或更改变量的类型.
这篇关于实体框架3.0包含无法像在EF Core 2.2中那样在SQL中进行翻译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!