.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))
PostAuthorはジャンクションテーブルであり、EF6に関与する必要のないジャンクションテーブル "AuthorInterest"もあります(Selectはa.Interestsに直接進みます)。
とにかく、EF7ではこれが修正されていることがわかります。つまり、ネストされたクエリにThenInclude()を使用する必要があるということです。しかしながら...
return _context.Post
.Include(p => p.PostAuthor)
.ThenInclude(pa => pa.Select(pa2 => pa2.Author))
...etc
上記のコードは、Select()ステートメントが原因で失敗します。 https://docs.efproject.net/en/latest/querying/related-data.html のドキュメントは、私はそれを必要とせず、すぐにAuthorにアクセスできることを示唆しているようですが、表示される最後のラムダのICollectionを取得するため、明らかにSelect()が必要です。クエリではさらに複数のジャンクションテーブルを調べますが、簡単にするために、最初のジャンクションテーブルだけに注目しましょう。
この作業を行うにはどうすればよいですか?
しかし、表示された最後のラムダでICollectionを取得するので、明らかにSelect()が必要です
いいえ、あなたはしません。 EF Core Include
/ThenInclude
は、EF6で使用されていたSelect
/SelectMany
の必要性を完全に置き換えます。どちらにも、コレクションおよび参照型のナビゲーションプロパティの個別のオーバーロードがあります。コレクションでオーバーロードを使用する場合、ThenInclude
はコレクションのタイプelementで動作するため、最後には常に単一のエンティティタイプになります。
あなたの場合、pa
はジャンクションテーブルの要素タイプに解決されるので、Author
に直接アクセスできる必要があります。
たとえば、EF6インクルードチェーン:
.Include(p => p.PostAuthor.Select(pa => pa.Author).Select(a => a.Interests))
eF Coreに変換します:
.Include(p => p.PostAuthor).ThenInclude(pa => pa.Author).ThenInclude(a => a.Interests)