EF CoreでJOINを複数する方法

目次

概要

ASP.NET Coreでデータベースへクエリを発行する際に、Entity Framework Core(EF Core)を使うのが一般的です。

今回、久しぶりにASP.NET Coreで1対多や多対多のリレーションを作成したのですが、Entity Framework Coreでリレーション先のデータを取得する方法に悩んでしまったので、備忘録として残しておきます。

環境

  • .NET 5
  • Entity Framework Core 5
  • ASP.NET Core 5

Includeを使った別テーブルのデータの読み出し

例えば、一つの記事(Articles)に複数のタグ(Tags)が結びつくような構造をもったテーブルを考えます。SQLとしては、JOINを使うようなものになります。

結論から話すと、次のようなコードで実現できます。

context.Articles
    .Include(a => a.Tags)
    .First()

このようにIncludeを使うことで、Articlesテーブルに紐づいた複数のTagsデータを取得できます。Includeは複数記述することが可能なので、例えばArticlesテーブルにカテゴリ(Categories)テーブルのリレーションがある場合は、次のようになります。

context.Articles
    .Include(a => a.Tags)
    .Include(a => a.Categories)
    .First()

ここまでは調べるとすぐに情報を見つけることができました。

私が本当に知りたかったのは、Includeで取得したデータからさらにIncludeのようなものでデータを取得するということです。SQLでいうならば、JOINでテーブルを結合してさらにJOINでテーブルを結合するというようなものです。

例えば、カテゴリからカテゴリの所有者を表すユーザー(Users)テーブルのリレーションがあったとします。そのような場合、次のようにすることで記事からユーザーの情報まで取得することができます。

context.Articles
    .Include(a => a.Tags)
    .Include(a => a.Categories)
    .ThenInclude(c => c.Users)
    .First()

Includeの直後にThenIncludeを記述することで、直前のIncludeで取得するデータについて、さらにデータを取得することができます。必ずThenIncludeはIncludeの直後に書かないといけないので、ここだけは注意が必要です。また、ThenIncludeもIncludeと同じように複数使うことができます。

これで、私が知りたいことを知ることができました。

さいごに

ASP.NET CoreやEntity Framework Coreの情報はあまり多くないので、少し見つけ出すのに苦労しました。

IncludeやThenIncludeは、組み合わせ爆発のような問題が発生することもあるので、利用する際は色々と気を付ける必要がありそうです。