【问题标题】:Pass arguments to IDesignTimeDbContextFactory of EF Core将参数传递给 EF Core 的 IDesignTimeDbContextFactory
【发布时间】:2021-09-08 08:01:25
【问题描述】:

我们如何将参数传递给 dotnet ef 数据库更新?

我希望能够使用参数更新不同的数据库。

我试过了

dotnet ef 数据库更新“接受”

dotnet ef 数据库更新接受

但它没有工作..

或者我如何设置开关以从我的配置中获取不同的 conenctionString?

public ProjectContext CreateDbContext(string[] args)
{
    IConfigurationRoot configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json")
        .Build();

    // Find a way to get different connection string 
    var connectionString = configuration.GetConnectionString(args[0]);

    var builder = new DbContextOptionsBuilder<ProjectContext >();
    builder.UseSqlServer(connectionString);

    return new ProjectContext(builder.Options);
}

【问题讨论】:

  • 你想同时访问两个数据库吗?
  • 我想根据一个参数值访问一个数据库,所以如果是Prod,去获取Prod连接字符串等

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


【解决方案1】:

.NET 5 将在此答案发布后的几周内发布。所以这是可以改变的。

立即回答

.NET 5 和相关的 EF Core 5+ NuGet 支持这一点。在包管理器中,您可以输入:

Add-Migration YourMigrationName -Args "Space Separated Args"
Update-Database -Args "Space Separated Args"

例如,我用这个:

Update-Database -Args MyConnName

在我的启动项目中,我有一个包含该连接字符串键的配置文件(或 appsettings.json),我将其拉入。

注意我说的是 .NET Core 5。这将在几周后发布完整版本。所以几周后这个答案可能很简单。但在那之前,您可能需要安装预览版(和 NuGet PreReleases)

现在之前回答

当被问到这个问题时,虽然有一些选择,比如将dotnet ef commandsAppArgs 一起使用,作为discussed here。但是这些已经改变,现在也可以从 PM 控制台访问,如上述“现在”答案中所述。

【讨论】:

    【解决方案2】:

    你也可以这样设置变量:

    $env:SqlConnectionString="Server=tcp:mySqlServerStuffxxx"
    Add-Migration InitialCreate
    Update-Database
    

    来源:

    https://dev.to/azure/using-entity-framework-with-azure-functions-50aa#adding-an-entity-framework-migration

    但它不适用于ConnectionStrings.DefaultConnection。它会给出以下错误:

    在此对象上找不到属性“DefaultConnection”。 验证该属性是否存在并且可以设置。

    【讨论】:

      【解决方案3】:

      从我在这里准备的所有内容中,我基本上以CreateDbContext(string[] args) 结束,args 将在您初始CMD 之后填充任何内容

      -- 标记指示 dotnet ef 将后面的所有内容视为 论点,而不是尝试将它们解析为选项。没有任何额外的论点 dotnet ef 使用的转发到应用程序。 more here

      将导致 args 填充 4 个参数 这是因为 -- 将所有其他内容传递回 dotnet 以设置参数

      例如,当将IDesignTimeDbContextFactory&lt;YourContext&gt; 接口添加到您的 Context 时,会添加以下方法,这是我可以传入 vars 的地方

          public DataBaseContext CreateDbContext(string[] args)
          {
              Debugger.Launch();
              Console.WriteLine($@"Args:");
              
              foreach (var arg in args)
              {
                  Console.WriteLine($"Arg: {arg}");
              }
          }
      

      这将写出 -test something -testagain again 中传递的 4 个变量 我发布此答案以帮助在此处扩展其他答案并查看完整的上下文

      【讨论】:

        【解决方案4】:

        我最近尝试让 Asp.Net Core 应用程序读取连接字符串时遇到了类似的问题。事实证明,您不需要IDesignTimeDbContextFactory。相反,只要确保你的上下文有一个无参数的构造函数,并在启动时使用这样的东西:

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        

        这应该解析为您配置的任何连接字符串。如果您确实想同时使用两个单独的连接(我意识到您不想要),您可以通过此时注册多个 DbContexts 来做到这一点;例如:

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        
        services.AddDbContext<MyDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("OtherConnection")));
        

        【讨论】:

        • 问:“我们如何传入参数”,答:“不要那样做。”这不是一个好的答案。您假设这里的关注点来自 ASP 启动项目,或者其他一些假设。问题只是你如何将 args 传递给这个显然接受 args 的对象。
        • 这个问题还有第二部分。我只是提供一种可能的解决方案。您显然可以自己提供替代答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 2021-08-02
        • 1970-01-01
        • 2017-08-25
        • 1970-01-01
        • 1970-01-01
        • 2023-01-30
        相关资源
        最近更新 更多