在实体框架中使用两个不同的连接字符串进行迁移

问题描述

我有一个 DbContext和两个数据库一个用于调试/开发(本地),一个用于生产(在线)。我用appsetting.Development.jsonappsettings.Production.json文件切换它们。

两者都看起来像这样:

{
  "ConnectionStrings": {
    "Default": "Server={myServer};Persist Security Info=False;User ID={MyUser};Password={myPassword};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
  }

因此,当我处理代码并启动它时,它将使用localDb,而在发布时,它将使用另一个数据库

现在,当我在模型中进行某些更改时,我总是必须删除迁移文件,然后再执行

dotnet ef migrations add InitialModel

然后

dotnet ef database update

之后,再次删除迁移文件,将appsettings.Development.json条目更改为我的在线数据库,然后再次执行命令。

这是我的问题:

  1. 是否可以选择在迁移命令中使用哪种配置? 喜欢:

     dotnet ef migrations add InitialModel --config Production
    
  2. 是否可以同时在两个数据库中使用迁移文件,这样我就不必总是删除迁移文件

解决方法

我不确定是否有一个Migration命令,让您选择配置,因为连接字符串已添加到Startup.cs文件中。但是,我可以分享我的操作方式,然后看看它是否对您有用。通常,我在appsettings.json文件中会有两个连接字符串。像这样 "ConnectionStrings": {"DevConnection": "Data source=databasename.db","ProdConnection":"Data source=databasename.db"},Startup.cs文件中,我在依赖项注入容器中指定连接字符串。在我的Program.cs文件中,我有这个

        var host = CreateHostBuilder(args).Build();
        using(var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;
            try
            {
                var context = services.GetRequiredService<DataContext>();
                var userManager = services.GetRequiredService<UserManager<AppUser>>(); //if you have users in your seed data
                context.Database.Migrate();
                Seed.SeedData(context,userManager).Wait(); //If you have seed data with test users

            }
            catch(Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex,"An error occurred during migration");
            }
        }
        host.Run();

这段代码确保您不需要运行Update database命令。您只需创建迁移并启动应用程序。 您只需要做的就是在开发之后,在Dependency Injection容器中切换连接字符串。切换连接字符串时,无需运行“更新数据库”命令。您也可以使用环境变量。您可以查看一下它的工作原理。