在连接表上使用EF Core ThenInclude()

nik*_*ovn 28 entity-framework entity-framework-core asp.net-core-mvc asp.net-core

我正在将我的.NET Framework(EF6)代码转移到ASP.NET Core(EF Core),我偶然发现了这个问题.这是一些示例代码:

在EF6中,我使用Include()和Select()进行预加载:

return _context.Post
.Include(p => p.PostAuthor.Select(pa => pa.Author).Select(a => a.Interests))
Run Code Online (Sandbox Code Playgroud)

PostAuthor是一个联结表,还有一个Junction表"AuthorInterest",我不需要参与EF6(Select直接进入a.Interests).

无论如何,我可以看到在EF7中这是重做的,这意味着我现在应该使用ThenInclude()来嵌套查询.然而...

return _context.Post
  .Include(p => p.PostAuthor)
    .ThenInclude(pa => pa.Select(pa2 => pa2.Author))
...etc
Run Code Online (Sandbox Code Playgroud)

由于Select()语句,上面的代码失败了.https://docs.efproject.net/en/latest/querying/related-data.html上的文档似乎表明我不需要它,我可以立即访问作者,但我在最后一个lambda中获得了ICollection显示,所以我显然需要Select().我在查询中进一步查看了多个联结表,但为了简单起见,我们只关注第一个.

我该如何工作?

Iva*_*oev 47

但是我在显示的最后一个lambda中得到了一个ICollection,所以我显然需要Select()

不,你没有.EF Core Include/ ThenInclude完全取代EF6 的需要Select/ SelectMany使用.它们对收集和引用类型导航属性都有单独的重载.如果对集合使用重载ThenInclude,则对集合元素的类型进行操作,因此最后总是以单个实体类型结束.

在您的情况下,pa应该解析您的联结表元素类型,因此Author应该可以直接访问.

例如,EF6包括链:

.Include(p => p.PostAuthor.Select(pa => pa.Author).Select(a => a.Interests))
Run Code Online (Sandbox Code Playgroud)

转换为EF Core:

.Include(p => p.PostAuthor).ThenInclude(pa => pa.Author).ThenInclude(a => a.Interests)
Run Code Online (Sandbox Code Playgroud)

  • 哇谢谢.非常奇怪 - 视觉工作室不会给我智能感知pa.Author(而是暗示一些Linq方法)并且一旦我尝试写它就会用红色强调所有内容.在你的帖子之后我忽视了VS并且在编译之后一切都像魅力一样. (23认同)
  • 我正在使用Visual Studio 2017 Preview 2,我得到了同样错误的intellisense.只需忽略它并成功构建:) (8认同)
  • 缺乏intellisense是罗斯林问题.请参阅https://github.com/dotnet/roslyn/issues/8237如果您使用的是像R#这样的第三方工具,那么它会扩展智能感知,以便为您提供正确的结果. (2认同)