具有多个提供程序的EF Core Migration始终运行SQL Server脚本

时间:2018-04-12 08:02:31

标签: c# .net entity-framework entity-framework-core

我首先使用EF Core Code,但在使用多个数据库提供程序(SQL Server和MySql)时遇到问题。 即使我选择使用MySql DB提供程序,也会使用SQL Server迁移文件。

检查示例project

2 个答案:

答案 0 :(得分:0)

在我的情况下,我对两个提供程序使用相同的迁移,但有时我需要手动对迁移文件进行一些更改。例如,为两个提供者添加了注释(或将某些字段的类型更改为 varchar nvarchar )。

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

对我而言,它的工作正常

答案 1 :(得分:0)

使用Entity Framework核心编写特定于提供程序的迁移,数据库初始化程序和服务可能是一项艰巨的任务。使用AdaptiveClient可以大大简化该过程。 AdaptiveClient是与Autofac一起使用的实用程序,用于针对多个数据库提供程序或传输提供服务层。 AdaptiveClient.EntityFrameworkCore是一个加载项,其中包含用于使用Entity Framework Core的实用程序。概括地说,这是AdaptiveClient的工作方式:

IMigrationContext是一个占位符接口,允许您将DbContext与特定的提供程序(MSSQL,MySql等)相关联,以创建迁移。 IDbContextOptions是一个占位符接口,允许您关联特定于您的提供程序的DbContextOptions实现。 RegistrationHelper是一个实用程序,可简化在Autofac中注册组件的过程。 RegisterMigrationContext是一种您可以调用的方法,可以轻松地注册特定于提供程序的迁移上下文。

要创建特定于提供程序的迁移,请为要定位的每个数据库提供程序创建一个类。这些类从您的DbContext派生并实现IMigrationContext(无成员):

public class MyDbContext_MSSQL : MyDbContext, IMigrationContext
{
    public MyDbContext_MSSQL(DbContextOptions options) : base(options)
    {

    }
}   


public class MyDbContext_MySQL : MyDbContext, IMigrationContext
{
    public MyDbContext_MySQL(DbContextOptions options) : base(options)
    {

    }
}

上面的示例是完整的-您不必编写任何其他代码。您不需要为每个提供程序创建一个单独的DbContext(除非您希望这样做)。您需要为每个提供程序创建一个类的原因是因为当您运行dotnet ef migrations add...时,EF会在您的程序集中反映出正确的DbContext。

创建包装DbContextOptions并实现IDbContextOptions的类:

public class DbContextOptions_MSSQL : IDbContextOptions
{
    public DbContextOptions Options { get; set; }

    public DbContextOptions_MSSQL(string connectionString)
    {
        DbContextOptionsBuilder builder = new DbContextOptionsBuilder();
        builder.UseSqlServer(connectionString);
        Options = builder.Options;
    }
}


public class DbContextOptions_MySQL : IDbContextOptions
{
    public DbContextOptions Options { get; set; }

    public DbContextOptions_MySQL(string connectionString)
    {
        DbContextOptionsBuilder builder = new DbContextOptionsBuilder();
        builder.UseMySql(connectionString);
        Options = builder.Options;
    }
}

使用AdaptiveClient RegistrationHelper向Autofac注册您的类:

registrationHelper.RegisterMigrationContext<Database.Db_MSSQL>(API_Name.MyAPI, DataBaseProviderName.MSSQL);
registrationHelper.RegisterMigrationContext<Database.Db_MySQL>(API_Name.MyAPI, DataBaseProviderName.MySQL);

registrationHelper.RegisterDbContextOptions<DbContextOptions_MSSQL>(DataBaseProviderName.MSSQL);
registrationHelper.RegisterDbContextOptions<DbContextOptions_MySQL>(DataBaseProviderName.MySQL);    

在上面的代码中,API_Name只是一个常量,可以解析为简单的字符串,例如“ MyApplicationName”。与DataBaseProviderName.MSSQL和.MySQL相同。它们是字符串常量,可以解析为“ MSSQL”或“ MySQL”。

现在,这是最重要的部分:正如使用“ MSSQL”或“ MySQL”之类的键注册应用程序的组件一样,您也使用相同的常量注册了应用程序的连接字符串。

这使Autofac可以仅基于当前用于应用程序的连接字符串来解析正确的特定于提供程序或特定于传输的组件。您可以阅读整个过程here

您可以在Zamagon Demo中看到完整的工作示例。该演示说明了迁移,数据库初始化程序以及用于集成测试的拖放方案。