Entity Framework CoreのMigrationをクラスライブラリに対して実施したい


はじめに

あるシステムを開発するのに、複数のプロジェクトに分けて開発するケースがあります。例えば、WebAPIはスマートフォンなどのアプリから呼び出され、Webアプリケーションはシステム運用で利用するみたいな例が考えられます。
あるいは、Webアプリケーションのプロジェクトと、Azure Functionsのプロジェクトの2つから構成されるものとか。

この時、Entity Framework CoreのEntityクラスとDBContextクラスは、どちらのプロジェクトでも共通なので、これも別のクラスライブラリ・プロジェクトとして独立させることになります。

以下のようなプロジェクト構成ですね。

Sample.sln
  Sample.Web Webアプリケーション。Sample.Dbを参照
  Sample.API Web APIプロジェクト。Sample.Dbを参照
  Sample.Db  DBのEntityクラスを定義したクラスライブラリ

課題

Entity Framework Coreのコードファーストで開発する場合、Migrationコードは、やはりSample.Dbプロジェクトに置きたいと思うのが普通だと思います。

しかし、Sample.Dbのあるフォルダに移動して、

dotnet ef migrations add NewMigration

のようにしても、このコードは以下のメッセージを出して失敗します。

Unable to create an object of type 'AppDbContext'. 
For the different patterns supported at design time,

実際に利用するデータベースプロバイダーやDBContextを見つけることができないからです。

Sample.WebやSample.APIのフォルダに移動して、上記コマンドを実行すれば成功しますが、それだとMigrationコードは、Sample.Dbには作成されません。

まあ、それでもいいのですが、やっぱりSample.Dbに作成したいですよね。少なくとも僕はそう思います。

解決策

こんな時は、以下のようなコマンドを打てばOKです。

dotnet ef migrations add NewMigration --startup-project ..//Sample.API

databaseに反映させるには、

dotnet ef database update --startup-project ..//Sample.API

Sample.APIのところは、Sample.WebでもOKです。

別解

Microsoftの公式ドキュメントの「別の移行プロジェクトを使用する」のページでは、別の方法も示されています。
こちらは、Webプロジェクトあるいは、APIプロジェクトのソースに、どのアセンブリにMigrationコードを生成するかを指定するコードを追加するというものです。

どちらも一長一短がありますが、ソースコードに手を入れたくない場合は、ここで示した--startup-projectオプションを使うのが良いと思います。