迁移多个提供程序Migrations with Multiple Providers

EF Core 工具仅基架活动提供程序的迁移。The EF Core Tools only scaffold migrations for the active provider. 但有时,您可能希望使用多个提供程序 (例如 Microsoft SQL Server 和 SQLite) DbContext。Sometimes, however, you may want to use more than one provider (for example Microsoft SQL Server and SQLite) with your DbContext. 可以通过两种方式来处理迁移。There are two ways to handle this with Migrations. 您可以维护两组迁移-每个提供程序一个,或将它们合并到可以同时使用的单个集。You can maintain two sets of migrations--one for each provider--or merge them into a single set that can work on both.

两个迁移集Two migration sets

第一种方法是为每个模型更改生成两个迁移。In the first approach, you generate two migrations for each model change.

实现此目的的一种方法是将每个迁移集放 在单独的程序集中 ,并在添加两个迁移之间手动切换活动提供程序 (和迁移程序集) 。One way to do this is to put each migration set in a separate assembly and manually switch the active provider (and migrations assembly) between adding the two migrations.

更轻松地使用工具的另一种方法是创建一个从 DbContext 派生的新类型并重写活动提供程序。Another approach that makes working with the tools easier is to create a new type that derives from your DbContext and overrides the active provider. 此类型在设计时用于添加或应用迁移。This type is used at design time when adding or applying migrations.

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

备注

由于每个迁移集使用自己的 DbContext 类型,因此此方法不需要使用单独的迁移程序集。Since each migration set uses its own DbContext types, this approach doesn't require using a separate migrations assembly.

添加新迁移时,指定上下文类型。When adding new migration, specify the context types.

dotnet ef migrations add InitialCreate --context MyDbContext --output-dir Migrations/SqlServerMigrations
dotnet ef migrations add InitialCreate --context MySqliteDbContext --output-dir Migrations/SqliteMigrations

提示

无需指定输出目录即可进行后续迁移,因为它们是以同级方式创建的。You don't need to specify the output directory for subsequent migrations since they are created as siblings to the last one.

一个迁移集One migration set

如果不喜欢两组迁移,可以手动将它们合并为可应用于这两个提供程序的单个集。If you don't like having two sets of migrations, you can manually combine them into a single set that can be applied to both providers.

批注可以共存,因为提供程序会忽略它不理解的任何批注。Annotations can coexist since a provider ignores any annotations that it doesn't understand. 例如,使用 Microsoft SQL Server 和 SQLite 的主键列可能如下所示。For example, a primary key column that works with both Microsoft SQL Server and SQLite might look like this.

Id = table.Column<int>(nullable: false)
    .Annotation("SqlServer:ValueGenerationStrategy",
        SqlServerValueGenerationStrategy.IdentityColumn)
    .Annotation("Sqlite:Autoincrement", true),

如果只能对一个提供程序应用操作,或它们在提供程序之间不同,请使用 ActiveProvider 属性来确定哪个提供程序处于活动状态:If operations can be applied only for one provider, or they're different between providers, use the ActiveProvider property to determine which provider is active:

if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.SqlServer")
{
    migrationBuilder.CreateSequence(
        name: "EntityFrameworkHiLoSequence");
}