移轉具有多個提供者Migrations with Multiple Providers

EF Core 工具只 scaffold 移轉為作用中的提供者。The EF Core Tools only scaffold migrations for the active provider. 有時候,不過,您可能想要使用您的 DbContext 中的多個提供者 (例如 Microsoft SQL Server 和 SQLite)。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.

Add-Migration InitialCreate -Context MyDbContext -OutputDir Migrations\SqlServerMigrations
Add-Migration InitialCreate -Context MySqliteDbContext -OutputDir Migrations\SqliteMigrations
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 only be applied on one provider (or they're differently between providers), use the ActiveProvider property to tell which provider is active.

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