C# 具有多个提供程序的EF Core迁移始终运行SQL Server脚本

C# 具有多个提供程序的EF Core迁移始终运行SQL Server脚本,c#,.net,entity-framework,entity-framework-core,C#,.net,Entity Framework,Entity Framework Core,我首先使用EF核心代码,在使用多个DB提供程序(SQL Server和MySql)时遇到问题。 即使我选择使用MySql DB provider,也会使用SQL server迁移文件 检查示例在我的例子中,我对两个提供程序使用相同的迁移,但有时需要手动对迁移文件进行一些更改。例如,为两个提供程序添加了注释(或者将一些字段的类型,如varchar更改为nvarchar) Id=table.Column(可空:false) .Annotation(“MySql:ValueGeneratedOnAdd

我首先使用EF核心代码,在使用多个DB提供程序(SQL Server和MySql)时遇到问题。 即使我选择使用MySql DB provider,也会使用SQL server迁移文件


检查示例

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

Id=table.Column(可空:false)
.Annotation(“MySql:ValueGeneratedOnAdd”,true)
.Annotation(“SqlServer:ValueGenerationStrategy”,SqlServerValueGenerationStrategy.IdentityColumn),

对我来说,编写特定于提供商的迁移、数据库初始值设定项和具有实体框架核心的服务可能是一项困难的任务。使用可大大简化流程。AdaptiveClient是一个实用工具,用于针对多个数据库提供程序或传输提供服务层。是一个附加组件,包括用于使用实体框架核心的实用程序。简而言之,AdaptiveClient的工作原理如下:

imiglationContext
是一个占位符界面,允许您将DbContext与特定的提供程序(MSSQL、MySql等)关联,以创建迁移。
IDbContextOptions
是一个占位符界面,允许您关联特定于您的提供者的DbContextOptions实现。
RegistrationHelper
是一个实用程序,可简化向Autofac注册组件的过程
RegisterMigrationContext
是一种方法,您可以调用它来轻松注册特定于提供商的迁移上下文

要创建特定于提供程序的迁移,您需要为要作为目标的每个数据库提供程序创建一个类。这些类派生自DbContext并实现
imiglationContext
(没有成员):

上面的例子是完整的-您不必编写任何额外的代码。您不需要为每个提供程序创建单独的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);    
registrationHelper.RegisterMigrationContext(API_Name.MyAPI,DataBaseProviderName.MSSQL);
registrationHelper.RegisterMigrationContext(API_Name.MyAPI,DataBaseProviderName.MySQL);
registrationHelper.RegisterDbContextOptions(DataBaseProviderName.MSSQL);
registrationHelper.RegisterDbContextOptions(DataBaseProviderName.MySQL);
在上面的代码中,API_Name只是一个常量,解析为一个简单的字符串,如“MyApplicationName”。与DataBaseProviderName.MSSQL和.MySQL相同。它们是解析为“MSSQL”或“MySQL”的字符串常量

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

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


您可以在中看到完整的工作示例。演示演示了迁移、数据库初始值设定项以及集成测试的删除和重新创建场景。

您必须使用
添加迁移-上下文“YourContextName”
@viveknuna我已经这样做了。如果您检查Migrations文件夹下的my sample project,就会看到一个
scripts.txt
。这些是我用来生成迁移文件的命令。这里的任何帮助都值得赞赏。您可以在本文中提出错误,这将帮助您管理两组迁移。我不想使用这种方法。拥有两个迁移集要干净得多。@pantoni如果你是对的,这只是人们可以使用的另外一种方法
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;
    }
}
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);