在 .NET Core 中的连接字符串之间轻松切换
Easily switching between connection strings in .NET Core
我有一个使用 EF Core 和 Dapper 对数据库执行操作的代码库。
我想设置一个新的网站副本来开发一些功能,我希望这个网站连接到数据库的一个新的独立副本 (dbConnectionDEBUG
)。
目前,我使用以下设置:
startup.cs
...
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("dbConnectionMain")));
services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
...
我有一个 ConnectionStrings
class 正在启动时通过 DI 正确填充:
public class ConnectionStrings
{
public string dbConnectionMain { get; set; }
public string dbConnectionDEBUG { get; set; }
public ConnectionStrings()
{
this.dbConnectionMain = "";
this.dbConnectionDEBUG = "";
}
}
然后,在我的 controllers/services 期间,我可以访问 ConnectionStrings
并且 99% 的时间我都在执行以下操作来进行数据库调用:
using (var conn = new SqlConnection(_connectionStrings.dbConnectionMain))
{
conn.Open();
...
如果我想切换到 'DEBUG' 数据库,这将导致大量代码更改。
如何根据我正在使用的系统版本轻松地在我的代码中的连接字符串之间切换。
如果我能以某种方式动态地做到这一点,那就太好了。明显的决定因素是 URL 网站正在运行。
或者,(作为单一更改)我是否只是手动更改源的连接字符串(例如 keystore/appsettings)。我不喜欢这个,因为它为人为错误留下了空间。
更新 (2)
根据@Nkosi 提到的,我正在走这条路:
- 始终使用一个连接字符串 'Id'(即
dbConnection
)
- 根据应用所在的环境 running/deployed 在
中区分连接字符串 值
我还有一个问题:
如果我有以下...
"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
值自动选择我的网站处于 Development
模式还是我必须手动添加 ASPNETCORE_ENVIRONMENT
值 Development
在我部署应用程序的服务器上?
附加:我的应用程序 运行 在 Azure 应用程序服务中。
更新 (3) - 任务完成
为了完成这个问题(以防万一有人需要知道这个),我根据@Nkosi 的建议进行了以下设置。
- 连接字符串 - 我有一个连接字符串 Id/name
dbConnection
用于所有 appSettings(见下文)
- 应用设置
- 我有一个默认
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,它存储了基于 Azure 的应用程序的所有密钥和机密。本地使用 User Secrets
。
对于简单的应用程序并使连接字符串远离我的存储库,我使用预处理器语句加上 PATH/System 变量,为了发布,我在 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;
}
}
}
我认为如果您为调试和主要添加 2 个连接,那么您将面临一些困难,因为更多的成员在您的团队中工作。可能是一些自己错误的使用release模式进行代码开发。
您可以试试这个 webconfig 方法:
public class 连接字符串
{
public 字符串 dbConnection { 得到;放; }
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>
ASP.NET Core reads the environment variable ASPNETCORE_ENVIRONMENT at app startup and stores the value in 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);
//...
})
//...
引用Use multiple environments in ASP.NET Core
我有一个使用 EF Core 和 Dapper 对数据库执行操作的代码库。
我想设置一个新的网站副本来开发一些功能,我希望这个网站连接到数据库的一个新的独立副本 (dbConnectionDEBUG
)。
目前,我使用以下设置:
startup.cs
...
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("dbConnectionMain")));
services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
...
我有一个 ConnectionStrings
class 正在启动时通过 DI 正确填充:
public class ConnectionStrings
{
public string dbConnectionMain { get; set; }
public string dbConnectionDEBUG { get; set; }
public ConnectionStrings()
{
this.dbConnectionMain = "";
this.dbConnectionDEBUG = "";
}
}
然后,在我的 controllers/services 期间,我可以访问 ConnectionStrings
并且 99% 的时间我都在执行以下操作来进行数据库调用:
using (var conn = new SqlConnection(_connectionStrings.dbConnectionMain))
{
conn.Open();
...
如果我想切换到 'DEBUG' 数据库,这将导致大量代码更改。
如何根据我正在使用的系统版本轻松地在我的代码中的连接字符串之间切换。 如果我能以某种方式动态地做到这一点,那就太好了。明显的决定因素是 URL 网站正在运行。
或者,(作为单一更改)我是否只是手动更改源的连接字符串(例如 keystore/appsettings)。我不喜欢这个,因为它为人为错误留下了空间。
更新 (2)
根据@Nkosi 提到的,我正在走这条路:
- 始终使用一个连接字符串 'Id'(即
dbConnection
) - 根据应用所在的环境 running/deployed 在 中区分连接字符串 值
我还有一个问题:
如果我有以下...
"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
值自动选择我的网站处于 Development
模式还是我必须手动添加 ASPNETCORE_ENVIRONMENT
值 Development
在我部署应用程序的服务器上?
附加:我的应用程序 运行 在 Azure 应用程序服务中。
更新 (3) - 任务完成
为了完成这个问题(以防万一有人需要知道这个),我根据@Nkosi 的建议进行了以下设置。
- 连接字符串 - 我有一个连接字符串 Id/name
dbConnection
用于所有 appSettings(见下文) - 应用设置
- 我有一个默认
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,它存储了基于 Azure 的应用程序的所有密钥和机密。本地使用 User Secrets
。
对于简单的应用程序并使连接字符串远离我的存储库,我使用预处理器语句加上 PATH/System 变量,为了发布,我在 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;
}
}
}
我认为如果您为调试和主要添加 2 个连接,那么您将面临一些困难,因为更多的成员在您的团队中工作。可能是一些自己错误的使用release模式进行代码开发。
您可以试试这个 webconfig 方法:
public class 连接字符串 { public 字符串 dbConnection { 得到;放; }
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>
ASP.NET Core reads the environment variable ASPNETCORE_ENVIRONMENT at app startup and stores the value in
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);
//...
})
//...