在.NET Core中轻松切换连接字符串

3
我有一个代码库,使用EF Core和Dapper来执行对数据库的操作。 我想建立一个新的网站副本以开发一些功能,并希望此站点连接到一个新的隔离数据库副本(dbConnectionDEBUG)。
目前,我使用以下设置:
startup.cs
...
services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(
        Configuration.GetConnectionString("dbConnectionMain")));

services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
...

我有一个ConnectionStrings类,它通过DI在启动时被正确地填充:

public class ConnectionStrings
{
    public string dbConnectionMain { get; set; }
    public string dbConnectionDEBUG { get; set; }

    public ConnectionStrings()
    {
        this.dbConnectionMain = "";
        this.dbConnectionDEBUG = "";
    }
}

然后,我可以在控制器/服务中访问 ConnectionStrings,99% 的时间都是用以下方式进行数据库调用:

using (var conn = new SqlConnection(_connectionStrings.dbConnectionMain))
{
    conn.Open();
    ...

如果我想要切换到“DEBUG”数据库,这将导致很多代码更改。

我该如何在我的代码中轻松地在连接字符串之间切换,取决于我正在处理哪个系统版本。如果我可以动态地做到这一点,那就太好了。明显的决定因素将是站点正在运行的URL。

或者,(作为单个更改)我只需在源头手动更改连接字符串(例如keystore / appsettings)。但我不喜欢这样做,因为它留下了人为错误的余地。


更新(2)

基于@Nkosi提到的内容,我正在追求这条路:

  • 使用一个连接字符串“Id”(即dbConnection
  • 根据应用程序在运行/部署的环境来区分连接字符串的value

我还有一个问题:

如果我有以下内容...

"MYAPPNAME": {
  "commandName": "Project",
  "launchBrowser": true,
  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
  },
  "applicationUrl": "http://localhost:12345/;https://myapptestdomain.com/"
}

并且:

WebHost.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((context, config) =>
    {
        IHostingEnvironment env = context.HostingEnvironment;

        config.AddJsonFile($"appsettings.{env.EnvironmentName.ToLower()}.json", optional: true);
        
    })
    .UseStartup<Startup>();

这会自动根据applicationUrl的值检测我的网站是否处于开发模式,还是我需要在我部署应用程序的服务器上手动添加值为DevelopmentASPNETCORE_ENVIRONMENT吗?
附加信息:我的应用程序正在运行在Azure应用程序服务中。
更新(3)-任务完成
只是为了完成这个问题(以防有人需要知道),我采用了@Nkosi的建议,有以下配置:
连接字符串 - 我有一个连接字符串ID/name dbConnection,它在所有appSettings中使用(见下文)
App Settings
我有一个默认的appSettings.json,其中包含一个查看实时数据库的dbConnection 我有一个额外的appSettings.Playground.json文件,其中包含一个查看测试数据库的dbConnection Azure - 应用程序服务 - 在我的playground开发槽上,我添加了一个ASPNETCORE_ENVIRONMENT的应用程序设置,其值为“Playground”
在我的Program.cs文件中,我有: config.AddJsonFile($"appsettings.json", optional: true,reloadOnChange: true);config.AddJsonFile($"appsettings.{env.EnvironmentName.ToLower()}.json", optional: true,reloadOnChange: true); 请注意,我还在Azure上初始化Vault,该Vault存储所有基于Azure的应用程序的密钥和密码。本地使用用户秘密。

2
你可以尝试使用环境变量来设置连接字符串。https://learn.microsoft.com/en-us/aspnet/core/fundamentals/environments - Nkosi
@Nkosi - 谢谢。我会去了解一下。 - scgough
@Nkosi,我已经在原始帖子中添加了更新。只剩一个问题:) - scgough
你需要对那个更新进行调整。 - Nkosi
@Nkosi,我应该如何将ASPNETCORE_ENVIRONMENT添加为Development到我的Azure应用程序配置中? - scgough
稍等,正在努力起草答案。 - Nkosi
3个回答

3

ASP.NET Core在应用程序启动时读取环境变量ASPNETCORE_ENVIRONMENT,并将值存储在IHostingEnvironment.EnvironmentName中。

由于环境已经加载,因此可以通过构建器上下文从托管环境中获取环境。

WebHost.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((context, config) => {
        string environment = context.HostingEnvironment.EnvironmentName; //get current environment

        //load config based on environment.
        config.AddJsonFile($"appsettings.{environment}.json", optional: true);
        //...
    })
    //...

参考 在 ASP.NET Core 中使用多个环境


谢谢,实际上我已经有这个可用的了,但为了我的回答简化了它。所以,唯一不确定的是 - 这是否会根据URL选择,还是我需要将 ASPNETCORE_ENVIRONMENT 添加到我的Azure应用服务设置中? - scgough
1
基于 ASPNETCORE_ENVIRONMENT 的 @scgough。 - Nkosi

0

对于简单的应用程序,为了将连接字符串与我的代码库分离,我使用预处理器语句加上路径/系统变量,在发布时我会在settings.json中提供一个连接字符串。

#define USE_FEATURE_X
using System;

namespace MyNamespace {
    internal static class StaticConnectionStringFactory {
        public static string GetConnectionString() {
#if DEBUG && !USE_FEATURE_X
            var connectionString = Environment.GetEnvironmentVariable("CNNSTR_SQL_XYZ", EnvironmentVariableTarget.User);
#elif DEBUG && USE_FEATURE_X
            var connectionString = Environment.GetEnvironmentVariable("CNNSTR_SQL_ABC", EnvironmentVariableTarget.User);
#else
            var connectionString = Environment.GetEnvironmentVariable("SqlConnectionString", EnvironmentVariableTarget.Process);
#endif
            return connectionString;
        }
    }
}

0

我认为如果你为调试和主要程序添加2个连接,你会面临一些困难,因为团队中有更多的成员在工作。可能会有人错误地使用发布模式进行代码开发。

你可以尝试这个WebConfig方法:

公共类 ConnectionStrings     {         public string dbConnection { get; set; }     }

    public ConnectionStrings()
    {
        bool Ismain = bool.Parse(System.Configuration.ConfigurationManager.AppSettings["HasLive"]);
        if (Ismain)
        {
            dbConnection = "";// get Main connectionstring
        }
        else
        {
            dbConnection = "";// get Debug connectionstring
        }

    }
}

web.config:

<connectionStrings>
  <add name="dbConnectionMain" connectionString="" providerName="System.Data.SqlClient" />
  <add name="dbConnectionDEBUG" connectionString="" roviderName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
  <add key="HasLive" value="false"/>  
</appSettings>
</connectionStrings>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接