EntityFrameworkの分割クエリと対応方法

目次

概要

最近、ASP.NET CoreでWebアプリケーションを作成しています。その際にデバッグをしていると、Warningが発生していることに気づきました。

今回は、この問題の解決方法について紹介します。

環境

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

警告の発生

今回私の環境で発生した警告文は次のものでした。

Compiling a query which loads related collections for more than one collection navigation either via ‘Include’ or through projection but no ‘QuerySplittingBehavior’ has been configured. By default Entity Framework will use ‘QuerySplittingBehavior.SingleQuery’ which can potentially result in slow query performance. See https://go.microsoft.com/fwlink/?linkid=2134277 for more information. To identify the query that’s triggering this warning call ‘Config
ureWarnings(w => w.Throw(RelationalEventId.MultipleCollectionIncludeWarning))’

内容としてEntity FrameworkのIncludeメソッドの利用の際にパフォーマンスの問題があるということのようです。

Includeメソッドは、1対多や多対多などのリレーションでデータを取得する際に利用するものです。

解決方法

今回のWarningは、Microsoftの次のWebページで詳しく説明されています。

単一クエリと分割クエリ - EF Core

デカルト爆発と呼ばれる現象が発生する可能性があり、それを防ぐための方法が用意されているので、対応をした方が良いということのようです。また、Entity Framework 5からの機能であるため、それよりも古いバージョンを利用している場合は、このような警告が表示されないようです。

今回私が採用した解決方法は、デフォルトで分割クエリを利用するように設定にするという方法です。

分割クエリは、デカルト爆発が起こらないようにクエリを分割して実行するという手法です。欠点として、分割してクエリを実行するので、それぞれのクエリ間で整合性が崩れる可能性があるということのようです。しかし、私の作成しているWebアプリケーションでは、多少の整合性には目をつぶることができるので、今回は分割クエリを採用しました。

分割クエリを採用する場合は、Startup.csファイルのConfigureServicesメソッドに次のようにコードを追加します。

services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(
        Configuration.GetConnectionString("DefaultConnection"),
        o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery)));

私の場合は、PostgreSQLをデータベースとして利用しているので、このように記述しました。

設定の肝となるのは、UseQuerySplittingBehaviorの部分です。もし、SQLServerなど別のデータベースを利用している場合は、UseQuerySplittingBehaviorメソッド以外の部分を適切に書き換える必要があります。

これで、今回のWarningが出ることがなくなりました。

さいごに

今回、デカルト爆発という単語を始めてみました。デカルト爆発という単語について、ネットで調べてみてもほとんど情報がないので、あまり意味が分かりませんが、おそらく組み合わせ爆発のようなものと考えてよさそうに思います。