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

EF 核心工具只 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 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");
}