使用多个提供程序进行迁移

EF Core 工具仅为活动提供程序提供基架迁移。 但是,有时可能想要将多个提供程序(例如 Microsoft SQL Server 和 SQLite)与 DbContext 结合使用。 通过维护多组迁移(每个提供程序一个)并针对每个模型更改添加迁移来解决该问题。

使用多个上下文类型

创建多个迁移集的一种方法是对每个提供程序使用一个 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

提示

不需要为后续迁移指定输出目录,因为它们是作为最后一个迁移的同级创建的。

使用一种上下文类型

也可使用一种 DbContext 类型。 目前,这需要将迁移移动到单独的程序集中。 有关如何设置项目的说明,请参阅使用单独的迁移项目

提示

可在 GitHub 上查看此文章的示例

可以将参数从工具传递到应用中。 这可实现更加简单的工作流,从而无需在运行工具时对项目进行手动更改。

下面是一种在使用通用主机时效果很好的模式。

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 未使用的任何额外参数都会转发到应用。