32

I'm transfering my .NET Framework (EF6) code to ASP.NET Core (EF Core), and I stumbled upon this issue. Here is some example code:

In EF6 I use Include() and Select() for eager-loading:

return _context.Post
.Include(p => p.PostAuthor.Select(pa => pa.Author).Select(a => a.Interests))

PostAuthor is a junction table and there is also a Junction table "AuthorInterest" which I didn't need to involve in EF6 (Select goes straight to a.Interests).

Anyway, I can see that in EF7 this is reworked, meaning that I should use ThenInclude() for nested queries now. However...

return _context.Post
  .Include(p => p.PostAuthor)
    .ThenInclude(pa => pa.Select(pa2 => pa2.Author))
...etc

The above code fails because of the Select() statement. The documentation on https://docs.efproject.net/en/latest/querying/related-data.html seems to suggest that I don't need it and I can access Author immediately, but I get an ICollection in the last lambda displayed, so I obviously need the Select(). I go through multiple junction tables further on in the query, but for simplicity's sake, let's just focus on the first one.

How do I make this work?

nikovn
  • 1,525
  • 4
  • 18
  • 28

1 Answers1

55

but I get an ICollection in the last lambda displayed, so I obviously need the Select()

No, you don't. EF Core Include / ThenInclude totally replace the need of Select / SelectMany used in EF6. Both they have separate overloads for collection and reference type navigation properties. If you use the overload with collection, ThenInclude operates on the type of the collection element, so at the end you always end up with a single entity type.

In your case, pa should resolve to your junction table element type, so Author should be directly accessible.

For instance the EF6 include chain:

.Include(p => p.PostAuthor.Select(pa => pa.Author).Select(a => a.Interests))

translates to EF Core:

.Include(p => p.PostAuthor).ThenInclude(pa => pa.Author).ThenInclude(a => a.Interests)
Ivan Stoev
  • 159,890
  • 9
  • 211
  • 258
  • 30
    Wow, thanks. Very weird - Visual studio would not give me intellisense for pa.Author (instead suggests some Linq methods) and would underline everything with red as soon as I try to write it. After your post I disregarded VS and after compiling everything worked like a charm. – nikovn Oct 29 '16 at 13:34
  • 1
    That's strange. I'm using VS2015 Update 3, and when I write something like `db.Parents.Include(p => p.Children).ThenInclude(c => c.Child).ThenInclude(c => c.Parents)` I get correct Intellisense support at each lambda. – Ivan Stoev Oct 29 '16 at 13:51
  • VS2015 Ultimate Update 3 here, too. Not too surprised, I have other bugs on core projects - for example when I select an item suggested by intellisense it writes the symbols in the middle of the file, etc. Maybe it's the plugins... – nikovn Oct 29 '16 at 20:01
  • Good comparison.+1 :) – Sampath Oct 30 '16 at 10:19
  • 8
    I am using Visual Studio 2017 Preview 2 and I get the same wrong intellisense. Just ignore that and build successfully :) – muhihsan Aug 09 '17 at 06:47
  • 1
    I am also having the IntelliSense issue in Visual Studio 2017 Pro, since there are a few others in the comments here having the issue I opened an issue on GitHub for the EF team: https://github.com/aspnet/EntityFramework/issues/9374 – Matt Sanders Aug 10 '17 at 02:58
  • 2
    The lack of intellisense is Roslyn issue. See https://github.com/dotnet/roslyn/issues/8237 If you are using 3rd party tool like R# then it extends intellisense to give you correct results. – Smit Aug 10 '17 at 05:18
  • Looks like this will be resolved in Roslyn in VS2019 Update 1, according to the linked ticket by @Smit. – Matt DeKrey Apr 22 '19 at 11:51