13

Ich übertrage meinen .NET Framework (EF6) Code auf ASP.NET Core (EF Core), und ich stolperte über dieses Problem. Hier einige Beispiel-Code:Verwenden von EF Core ThenInclude() auf Junction-Tabellen

In EF6 I Include() und Select() für eifrige-Laden:

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

PostAuthor ist eine Verknüpfungstabelle und es gibt auch eine Junction Tabelle "AuthorInterest", die ich musste nicht in EF6 involviert sein (Select geht direkt zu a.Interests).

Wie auch immer, ich kann sehen, dass in EF7 dies überarbeitet wird, was bedeutet, dass ich ThenInclude() für verschachtelte Abfragen jetzt verwenden sollte. Jedoch ...

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

Der obige Code schlägt aufgrund der Anweisung Select() fehl. Die Dokumentation auf https://docs.efproject.net/en/latest/querying/related-data.html scheint darauf hinzuweisen, dass ich es nicht brauche und ich kann sofort auf Author zugreifen, aber ich bekomme eine ICollection im letzten Lambda angezeigt, also brauche ich offensichtlich die Select(). Ich gehe in der Abfrage weiter durch mehrere Verzweigungstabellen, aber um der Einfachheit willen konzentrieren wir uns nur auf den ersten.

Wie mache ich das?

Antwort

22

aber ich bekomme eine ICollection in der letzten Lambda angezeigt, also muss ich natürlich die Select()

Nein, Sie nicht. EF Core Include/ThenInclude ersetzen vollständig die Notwendigkeit von Select/ in EF6 verwendet. Beide haben unterschiedliche Überladungen für die Navigationseigenschaften der Sammlung und des Referenztyps. Wenn Sie die Überladung mit Sammlung verwenden, arbeitet ThenInclude auf den Sammlungsart Element, so dass Sie am Ende immer mit einem einzigen Entitätstyp enden.

In Ihrem Fall sollte pa zu Ihrem Junction-Tabellenelementtyp aufgelöst werden, so dass Author direkt zugänglich sein sollte.

Zum Beispiel die EF6 umfassen Kette:

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

übersetzt EF Kern:

.Include(p => p.PostAuthor).ThenInclude(pa => pa.Author).ThenInclude(a => a.Interests) 
+4

Wow, danke. Sehr komisch - Visual Studio würde mir keine Intellisense für pa.Author geben (stattdessen schlägt man einige Linq-Methoden vor) und würde alles mit rot unterstreichen, sobald ich versuche, es zu schreiben. Nach deinem Beitrag ignorierte ich VS und nach dem Kompilieren funktionierte alles wie ein Zauber. – nikovn

+1

Das ist seltsam. Ich verwende VS2015 Update 3, und wenn ich etwas wie "db.Parents.Include (p => p.Children) schreibe. DannInclude (c => c.Child) .ThenInclude (c => c.Parents)' I Holen Sie sich die korrekte Intellisense-Unterstützung bei jedem Lambda. –

+0

VS2015 Ultimate Update 3 auch hier. Nicht zu überrascht, ich habe andere Bugs in Kernprojekten - zum Beispiel wenn ich ein von intellisense vorgeschlagenes Element auswähle, schreibt es die Symbole in die Mitte der Datei usw. Vielleicht sind es die Plugins ... – nikovn