複数のプロバイダーを使用した移行

EF Core ツールでは、アクティブなプロバイダーの移行のみをスキャフォールディングします。 ただし、DbContext で複数のプロバイダー (たとえば、Microsoft SQL Server と SQLite) を使用する場合があります。 これを処理するには、複数の移行セット (プロバイダーごとに 1 つ) を維持し、モデルの変更ごとにそれぞれに移行を追加します。

複数のコンテキスト型の使用

複数の移行セットを作成するための 1 つの方法は、プロバイダーごとに 1 つの DbContext 型を使用する方法です。

class SqliteBlogContext : BlogContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options.UseSqlite("Data Source=my.db");
}

新しい移行を追加するときにコンテキスト型を指定します。

dotnet ef migrations add InitialCreate --context BlogContext --output-dir Migrations/SqlServerMigrations
dotnet ef migrations add InitialCreate --context SqliteBlogContext --output-dir Migrations/SqliteMigrations

ヒント

後続の移行のための出力ディレクトリは最後のディレクトリの兄弟として作成されるため、これらを指定する必要はありません。

1 つのコンテキスト型の使用

1 つの DbContext 型を使用することもできます。 現時点では、移行を別のアセンブリに移動する必要があります。 プロジェクトを設定する手順については、「別の移行プロジェクトを使用する」を参照してください。

ヒント

この記事のサンプルは GitHub で確認できます。

引数をツールからアプリに渡すことができます。 これにより、ツールの実行中にプロジェクトに手動で変更を加える必要が生じない、より合理化されたワークフローが可能です。

汎用ホストを使用する場合にうまく機能する 1 つのパターンを、次に示します。

public static IHostBuilder CreateHostBuilder(string[] args)
    => Host.CreateDefaultBuilder(args)
        .ConfigureServices(
            (hostContext, services) =>
            {
                services.AddHostedService<Worker>();

                // Set the active provider via configuration
                var configuration = hostContext.Configuration;
                var provider = configuration.GetValue("Provider", "SqlServer");

                services.AddDbContext<BlogContext>(
                    options => _ = provider switch
                    {
                        "Sqlite" => options.UseSqlite(
                            configuration.GetConnectionString("SqliteConnection"),
                            x => x.MigrationsAssembly("SqliteMigrations")),

                        "SqlServer" => options.UseSqlServer(
                            configuration.GetConnectionString("SqlServerConnection"),
                            x => x.MigrationsAssembly("SqlServerMigrations")),

                        _ => throw new Exception($"Unsupported provider: {provider}")
                    });
            });

既定のホスト ビルダーでは、コマンド ライン引数から構成が読み取られるため、ツールを実行するときにプロバイダーを指定できます。

dotnet ef migrations add MyMigration --project ../SqlServerMigrations -- --provider SqlServer
dotnet ef migrations add MyMigration --project ../SqliteMigrations -- --provider Sqlite

ヒント

-- トークンは、後に続くすべてのものを引数として扱い、それらをオプションとして解析しないことを dotnet ef に指示します。 dotnet ef によって使用されない追加の引数はアプリに転送されます。