はじめに
ASP.NET Core でMVCのアプリを作ろうとした際、複数のプロジェクトで利用することを想定し、
Entity + DbContextを別プロジェクト(クラスライブラリ)としました。
しかしよく考えたら StartUp.cs
も appsetting.json
も無いのにどうやってマイグレーションをすればいいんだ?と思い調査したところ、自分の環境でうまくいく方法があったので、紹介します。
筆者の環境
- OS: macOS Mojave 10.14.5
- ASP.NET Coreのバージョン: 2.2
やり方(抜粋)
-
クラスライブラリ側にnugetのEF Core関連パッケージを追加します
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Relational
Microsoft.EntityFrameworkCore.SqlServer
-
DbContextをクラスライブラリ側に追加します
-
MVC側
appsetting.json
に接続文字列を追加して、StartUp.cs
のDbContextのDI部分を以下のようにしますStartup.csservices.AddDbContext<MyProjectEntitiesDbContext>(options => { options.UseSqlSer:ve::r(Configuration.GetConnectionString("DefaultConnection"), assembly => assembly.MigrationsAssembly(typeof(MyProjectEntitiesDbContext).Assembly.FullName)); });
-
MVC側プロジェクトディレクトリ内でコマンドを叩きます
# --project: クラスライブラリの .csproject パス # --startup-project: MVC(クラスライブラリを利用する側)の .csproject パス dotnet ef migrations add InitialMigrations --project ../MyProjectEntities/MyProjectEntities.csproj --startup-project ./MyProjectMVC.csproj dotnet ef database update
やり方(ソリューション作成からの一連の流れ)
1. ソリューション & 各プロジェクト作成
- MVC:
MyProjectMVC
- クラスライブラリ:
MyProjectEntities
2. クラスライブラリ側
2-1. Personクラスを作成
Entities
ディレクトリ下に普通に作ります
namespace MyProjectEntities.Entities
{
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
}
2-2. EF Core関連のnuget パッケージインストール
以下の3つのパッケージをインストールします
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Relational
Microsoft.EntityFrameworkCore.SqlServer
2-3. DbContextを作成する
今回はData
ディレクトリ下に作成しました(場所はどこでも良いはず)
using System.Linq;
using MyProjectEntities.Entities;
using Microsoft.EntityFrameworkCore;
namespace MyProjectEntities.Data
{
namespace MyProjectEntities.Data
{
public class MyProjectEntitiesDbContext : DbContext
{
public MyProjectEntitiesDbContext(DbContextOptions<MyProjectEntitiesDbContext> options)
: base(options)
{
}
public DbSet<Person> Persons { get; set; }
}
}
}
これでクラスライブラリ側の作業は終わりです。
3. MVC側
3-1. appsetting.json
への接続文字列追加
普通に追加します
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "hogehogefugafuga"
}
}
3-2. StartUp.cs
で DbContextをDI
assembly => assembly.MigrationsAssembly(typeof(クラスライブラリDbコンテキスト名).Assembly.FullName));
が通常と異なる部分です。
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<MyProjectEntitiesDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
assembly => assembly.MigrationsAssembly(typeof(MyProjectEntitiesDbContext).Assembly.FullName));
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
これでMVC側の作業は終わりです。
4. マイグレーション実施
4-1. MVCプロジェクトのディレクトリに移動
コンソールで ソリューションのディレクトリ
> MVCプロジェクトのディレクトリ
に移動します。
~/P/MyProject ❯❯❯ ls
MyProject.sln MyProjectEntities MyProjectMVC
~/P/MyProject ❯❯❯ cd MyProjectMVC
4-2. マイグレーションのコマンドを叩く
通常はdotnet ef migrations add ${マイグレーションファイル名}
でよいのですが、
今回は以下のようにします
dotnet ef migrations add ${マイグレーションファイル名} --project ${クラスライブラリの.csprojパス} --startup-project ${MVCプロジェクトの.csprojパス}
~/P/M/MyProjectMVC ❯❯❯ dotnet ef migrations add InitialMigrations --project ../MyProjectEntities/MyProjectEntities.csproj --startup-project ./MyProjectMVC.csproj
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 2.2.6-servicing-10079 initialized 'MyProjectEntitiesDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: MigrationsAssembly=MyProjectEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Done. To undo this action, use 'ef migrations remove'
4-3. DB反映
こちらは特に引数などは必要なく、普通に叩きます
~/P/M/MyProjectMVC ❯❯❯ dotnet ef update