移行は、 DbContextを含むプロジェクトとは異なるプロジェクトに格納できます。 これは、アプリケーション プロジェクトがプラットフォーム固有 (WinUI、.NET MAUI、Blazor WebAssembly、Azure Functionsなど) の場合、または特定のランタイム識別子 (RID) を対象とする場合に推奨されます。 また、複数の移行セットを維持するためにも使用できます。
Tip
この記事の サンプルは、GitHub で確認できます。
プロジェクトのレイアウト
このサンプルでは、次の 3 つのプロジェクトを使用します。
| プロジェクト | 責任 | References |
|---|---|---|
WebApplication1.Data |
DbContextとエンティティ型を所有します |
EF Core プロバイダー |
WebApplication1.Migrations |
移行、モデル スナップショット、およびデザイン時コンテキストの作成を所有します | データ プロジェクト、EF Core プロバイダー、および Microsoft.EntityFrameworkCore.Design |
WebApplication1 |
アプリケーションを実行する | データ プロジェクトと移行プロジェクト |
アプリケーションは、実行時に移行を検出または適用するときに、たとえば Migrateを呼び出すことによって、移行プロジェクトへの参照を必要とします。 移行がデプロイ成果物によってのみ適用され、アプリケーションがそれらを読み込まない場合、その参照は必要ありません。
プロジェクトを構成する
移行用のクラス ライブラリを作成し、
DbContextを含むプロジェクトへの参照を追加します。データベース プロバイダーと
Microsoft.EntityFrameworkCore.Designを移行プロジェクトに追加します。 設計パッケージをプライベート開発依存関係としてマークします。<ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="..."> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="..." /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\WebApplication1.Data\WebApplication1.Data.csproj" /> </ItemGroup>移行プロジェクトに
IDesignTimeDbContextFactory<TContext>を実装します。 ファクトリでは、アプリケーション プロジェクトを実行せずに、ツールでコンテキストを作成できます。public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext> { public ApplicationDbContext CreateDbContext(string[] args) { var connectionString = args.FirstOrDefault() ?? @"Server=(localdb)\mssqllocaldb;Database=WebApplication1;Trusted_Connection=True"; var options = new DbContextOptionsBuilder<ApplicationDbContext>() .UseSqlServer( connectionString, sqlServer => sqlServer.MigrationsAssembly(typeof(ApplicationDbContextFactory).Assembly.GetName().Name)) .Options; return new ApplicationDbContext(options); } }デザイン時プロバイダーとモデルの構成は、ランタイム構成と一貫性を保ちます。 このサンプルでは、省略可能な接続文字列引数を受け取り、引数が指定されていない場合はローカル開発接続を使用します。
実行時にコンテキストを登録するときに、移行アセンブリを構成します。
services.AddDbContext<ApplicationDbContext>( options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"), x => x.MigrationsAssembly("WebApplication1.Migrations")));アプリケーションが移行を適用する場合、または実行時にそれらを検出する場合は、アプリケーションから移行プロジェクトへの通常の参照を追加します。
<ItemGroup> <ProjectReference Include="..\WebApplication1.Migrations\WebApplication1.Migrations.csproj" /> </ItemGroup>データ プロジェクトは、移行プロジェクトを参照してはなりません。 移行プロジェクトが既にデータ プロジェクトを参照しているため、循環依存関係が作成されます。
移行が既に存在する場合は、すべての移行ファイルとモデル スナップショットを移行プロジェクトに移動し、名前空間を更新します。 既存の移行がない場合、デザイン時ファクトリでは、移行プロジェクトで最初の移行を直接作成できます。
ツールを使用する
移行プロジェクトを ターゲット プロジェクトとスタートアップ プロジェクトの両方として使用します。 ターゲット プロジェクトは生成されたファイルを受け取りますが、スタートアップ プロジェクトはツールによってビルドおよび実行されます。 このレイアウトでは、両方に移行プロジェクトを使用すると、ツールでアプリケーションのスタートアップ コードが実行されなくなります。
ソリューション ディレクトリから次のコマンドを実行します。
dotnet ef migrations add NewMigration \
--project WebApplication1.Migrations \
--startup-project WebApplication1.Migrations
同じプロジェクト オプションが他のコマンドに適用されます。
dotnet ef migrations list \
--project WebApplication1.Migrations \
--startup-project WebApplication1.Migrations
dotnet ef migrations script --output artifacts/migrations.sql \
--project WebApplication1.Migrations \
--startup-project WebApplication1.Migrations
dotnet ef migrations bundle --output artifacts/efbundle \
--project WebApplication1.Migrations \
--startup-project WebApplication1.Migrations
EF Core 11 以降では、繰り返しのプロジェクト オプションを .config/dotnet-ef.jsonに格納できます。
--no-buildを使用してコマンドを実行する前、または別のプロセスがその出力を使用する前に、移行プロジェクトをビルドします。 通常の dotnet ef コマンドは、ターゲット プロジェクトとスタートアップ プロジェクトを自動的にビルドします。
プラットフォーム固有のアプリケーション
EF ツールのスタートアップ プロジェクトとしてプラットフォーム固有のアプリケーション プロジェクトを使用しないでください。 モバイル、ブラウザー、デスクトップ、関数、RID 固有のプロジェクトでは、 dotnet ef 実行できないワークロードまたはネイティブ ホストが必要な場合があります。 EF Core 11 以降では、プラットフォーム固有のスタートアップ プロジェクトが使用されると、ツールによって警告が表示されます。
上記のレイアウトは、.NET MAUI、WinUI、Blazor WebAssembly、Azure Functions、および同様のアプリケーションに使用します。
- コンテキストとエンティティの種類を共有データ プロジェクトに配置します。
- 移行と
IDesignTimeDbContextFactory<TContext>は、通常のクロスプラットフォーム .NET プロジェクトに配置します。 - 移行プロジェクトをターゲット プロジェクトとスタートアップ プロジェクトとして使用してツールを実行します。
- アプリケーションが実行時に移行を読み込んだり適用したりする場合にのみ、アプリケーションから移行プロジェクトを参照します。
Xamarinおよび MAUI プラットフォーム プロジェクトの直接ツールサポートは計画されていません。dotnet/efcore#7152 を参照してください。 Xamarinアプリケーションは、最初に.NET MAUIにアップグレードする必要があります。
プロセス アーキテクチャ
ツールを実行するプロセスは、すべてのデザイン時アセンブリを読み込める必要があります。 64 ビットのVisual Studioまたは.NET プロセスでは、x86 のみのスタートアップ アセンブリを読み込めません。Arm64 やその他のアーキテクチャにも同じ制約が適用されます。 AnyCPU 移行プロジェクトを優先します。 デザイン時の依存関係に特定のアーキテクチャが必要な場合は、一致する.NET SDK を明示的に呼び出します。
デザイン時プロセス アーキテクチャは、デプロイ ターゲットとは別です。 バンドルを作成するときは、 --target-runtime または -TargetRuntime を使用して、 linux-arm64 や osx-arm64などのデプロイ RID の成果物を生成します。
.NET