我正在尝试在运行时更改位于我们服务主机的 App.Config 中的连接字符串中的数据库名称,然后在连接到另一个数据库后重新启动它。这很好用,但前提是应用程序关闭了几秒钟。关闭应用程序几秒钟似乎清除了 ConfigurationManager.Connectionstrings 的缓存。问题是由于需要关闭时间,我不能在我的应用程序中使用 Application.Restart() 。
这种缓存行为的奇怪之处在于,即使在内存中更新了值(在示例中是第二次请求),更新的值也会正确显示。但是当应用程序重新启动时,旧值似乎重新出现。
要验证行为,请创建一个新的控制台应用程序。
添加一个 App.Config 文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="DomainDBConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=InitialDBName;Integrated Security=SSPI;" />
</connectionStrings>
</configuration>
然后将以下代码添加到 Main 方法中
ConfigurationManager.RefreshSection("connectionStrings");
DbConnectionStringBuilder builder = new DbConnectionStringBuilder();
Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
builder.ConnectionString = appConfig.ConnectionStrings.ConnectionStrings["DomainDBConnectionString"].ConnectionString;
//print initial value
Console.WriteLine("initial " + (string)builder["Initial Catalog"]);
//change value
builder["Initial Catalog"] = "ChangedDatabaseName";
appConfig.ConnectionStrings.ConnectionStrings.Remove("DomainDBConnectionString");
appConfig.ConnectionStrings.ConnectionStrings.Add(new ConnectionStringSettings("DomainDBConnectionString", builder.ConnectionString));
appConfig.ConnectionStrings.SectionInformation.ForceSave = true;
appConfig.Save(ConfigurationSaveMode.Full);
ConfigurationManager.RefreshSection("connectionStrings");
Console.ReadLine();
DbConnectionStringBuilder builder2 = new DbConnectionStringBuilder();
Configuration appConfig2 = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
builder2.ConnectionString = appConfig.ConnectionStrings.ConnectionStrings["DomainDBConnectionString"].ConnectionString;
Console.WriteLine("changed " + (string)builder2["Initial Catalog"]);
Console.ReadLine();
要重现此行为,您需要运行应用程序(按 F5)并关闭它。之后 solutionname.exe.config 文件将显示修改后的值。如果您第二次运行该应用程序(这次是通过双击 solutionname.exe),您会注意到如果您在终止应用程序后立即执行此操作,或者在您等待几秒钟后执行此操作,则会出现不同的行为。
在我看来,应该重新读取配置部分,因为 ConfigurationManager.RefreshSection("connectionStrings"); 但显然这并不像宣传的那样有效。