【问题标题】:Entity Framework Core 3.1 anonymous projections cannot now be used in Linq include statements?Entity Framework Core 3.1 匿名投影现在不能在 Linq 包含语句中使用?
【发布时间】:2020-03-05 04:45:58
【问题描述】:

所以我从第 4 版开始就一直在使用 Entity Framework,并且最近在我正在做的一个项目中进行了一些重大更改。可以说我正在使用 EF 在使用 EF Core 3.1.2(即 EF Core 2.2.6)的 ETL 过程中获取从一个数据库到另一个数据库的差异。现在正在破坏的部分具有与此类似的代码。

var setOne = await 1stContext.table.Where(x => x.DateModified >= inputDate)).Select(x => new { x.UserId, x.RoleId, x.UniversityId }).ToListAsync();

var toRemove = 2ndContext.table.Where(x => setOne.Contains(new { x.UserId, x.RoleId, x.UniversityId })).ToList();

以前有一个匿名投影“new { (items) }”可以工作,但现在它崩溃了。我尝试转换为自 C# 7 以来新的命名元组,但根据编译器,您不能在表达式树中执行此操作。那么关于新方法的任何想法?也许只是做一个 linq join 或类似的?我的想法总是在实现数据之前先执行 where 子句,这样等效的 sql 就不会给我所有的结果,然后再遍历它们。

更新 这是一个简单的打印屏幕,没有我的意思。我一直用非常宽的集合来做这个,我只想做一个较小的集合然后找到它。我可以加入,但关键是,如果你看一下我的第二条语句,我还没有用“toList”投射到一个真实的对象上,如果我这样做了,我将失去获取我想要删除的对象的能力。我可能会加入,但我只是不想进行昂贵的数据库调用来获取所有内容并进行过滤。但是加入可能会起作用。我明天可能会在工作中玩这个,但如果有人知道的话,我只是想把它放在这里。

【问题讨论】:

  • 我的立场是正确的 :)
  • Contains 在非原始类型内存收集上从未在 EF / EF Core 中工作过。在 EF Core 1.x / 2.x 中,它可能看起来工作,但实际上这是由于客户端评估,它基本上在从数据库中检索所有数据后在内存中执行过滤。这与在Where 之前添加.AsEnumerable() 相同。
  • @IvanStoev 啊,我从来不知道。因此,如果不先进行投影并在整个时间稍后保持 SQL,那么连接可能会更好?
  • 好吧,不幸的是,不支持涉及多个上下文/数据库的查询。
  • 查看此 SO 帖子以获得可能的解决方案 - stackoverflow.com/questions/26198860/…(适用于 EF6,但同样适用于 EFC)。你也可以看看这个 3rd 方包EntityFrameworkCore.MemoryJoin - 我从来没有尝试过,不知道它是否支持 EFC 3.x

标签: c# entity-framework linq .net-core-3.1 entity-framework-core-3.1


【解决方案1】:

根据 Ivan Stoev 所说,我只是将“AsEnumerable”放在实体声明之后和 where 之前。似乎 EF Core 3.1 比以前的迭代要严格得多。

所以这个:

2ndContext.table.Where

变成了这样:

2ndContext.table.AsEnumerable().Where

只是基本上明确地说明,从我从其他人那里收集到的信息中,这暗示了我之前的客户。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-14
    • 2020-05-11
    • 2020-05-17
    • 1970-01-01
    • 2020-06-02
    • 2016-08-04
    • 1970-01-01
    • 2020-08-16
    相关资源
    最近更新 更多