Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework core 实体框架3.0包含的内容不能像在EF Core 2.2中那样在SQL中转换_Entity Framework Core_.net Core 3.0_Entity Framework Core 3.0 - Fatal编程技术网

Entity framework core 实体框架3.0包含的内容不能像在EF Core 2.2中那样在SQL中转换

Entity framework core 实体框架3.0包含的内容不能像在EF Core 2.2中那样在SQL中转换,entity-framework-core,.net-core-3.0,entity-framework-core-3.0,Entity Framework Core,.net Core 3.0,Entity Framework Core 3.0,我正在尝试将Web API从.NET Core 2.2迁移到.NET Core 3.0,但遇到以下问题: public Dictionary<int, Tag> GetTagMap(IList<int> tagIds = null) { var tags = context.Tag.AsNoTracking(); if (tagIds != null) tags = tags.Where(t => tagIds.Contains(t.

我正在尝试将Web API从.NET Core 2.2迁移到.NET Core 3.0,但遇到以下问题:

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);
}
对于正确索引的列和少量的
IN
值,它非常有效

现在我收到以下错误,提示不再支持
List.Contains
翻译:

System.InvalidOperationException:“LINQ表达式”其中( 来源:DbSet,谓词:(t)=>(未处理的参数: __无法翻译tagIds_0).Contains(t.TagId))'。以可以翻译的形式重写查询,或者切换到 通过插入一个调用 AsEnumerable()、AsAsAsyncEnumerable()、ToList()或ToListSync()。看见 客户端与服务器评估-有关更多信息,请参阅EF Core。”


这表明发生了突破性的变化,但客户端没有对AFAIK
包含的内容进行评估。

我了解发生了什么,以及为什么我的代码没有按预期运行(服务器端评估),以及为什么显式客户端评估实际上是一件非常好的事情:

IList.Contains
实际上是在客户端计算的,但是
List.Contains
是在服务器端计算的。简单地用List替换
IList
,使代码在没有显式客户端评估的情况下工作:

public Dictionary<int, Tag> GetTagMap(List<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);
}
public Dictionary GetTagMap(List tagid=null)
{
var tags=context.Tag.AsNoTracking();
if(tagIds!=null)
tags=tags.Where(t=>TagId.Contains(t.TagId));
返回标签
.ToList()//3.0中的显式客户端评估
.ToDictionary(t=>t.TagId,t=>t);
}

这是一个3.0错误,由跟踪

已在3.1中修复。例如,解决方法(如果您不能等待)是强制使用
Enumerable.Contains

t => tagIds.AsEnumerable().Contains(t.TagId)

或者更改变量的类型。

,那么任何关键字也不起作用吗?@BeiBeiZHU-这很有用,我刚刚意识到我的代码有什么问题,以及为什么显式客户端评估是一个很好的改进。我会尽快发布我的答案。谢谢。真有趣。。IList和List具有不同的行为。。学习..这是一个bug的迹象-一个
列表
是一个
IList
并且应该以同样的方式运行。无论您如何看待客户端评估,它都是一个非常糟糕的想法,这就是为什么在EF1.0将LINQ替换为SQL时它被删除的原因。太多的人在没有意识到的情况下将整个表加载到内存中。。为什么人们认为把它带回来是个好主意,这是世界上的一个谜Universe@PanagiotisKanavos-我认为客户端评估的主要优点是允许更自然的代码(只需获取一些数据+进行一些转换)。然而,将其隐式化显然是不好的,因为许多人没有看到潜在的性能问题。嗨,你能回答这个问题吗?谢谢嗨,你能回答这个问题吗?谢谢嗨,我想虫子没被发现fixed@AlanSmith5482我的测试表明它确实已修复。错误历史记录显示,它在2019年9月3日被标记为关闭/修复,在10月重新打开并再次关闭,错误的最后一次活动是在2019年12月。如果错误修正是错误的,EF团队可能没有意识到这一点。
t => tagIds.AsEnumerable().Contains(t.TagId)