0

I have a single connection string in my app.config. I connect to a setting database to retrieve additional connection strings. I write these additional connection strings to my app.config at runtime. Everything seems to work as expected but Entity Framework seems oblivious to the changes and throws an exception when trying to use one of the additional connection strings.

Steps below:

  • Clean solution.
  • Debug
  • [my program].exe.Config is copied to bin/Debug with single connection string
  • Entity Framework connects to settings database and retrieves additional connection strings
  • Update connectionStrings section in [my program].exe.Config with additional connection strings. File in bin/Debug is definitely updated.
  • Instantiate Entity Framework context for different database using one of the additional connection strings from earlier step
  • Call context.[anything].ToList() throws exception 'Value cannot be null. Parameter name: connection'
  • context.Database.Connection is null which I assume explains the exception?

Process terminates. Re-run debug without cleaning solution so the connection strings from previous run are still in [my program].exe.Config. Entity Framework no longer throws exception. Based on this I believe the connection strings are valid, but Entity Framework just doesn't see them the first time around.

Code

    private void SetConnectionStrings()
    {
        var configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        var section = (ConnectionStringsSection)configuration.GetSection("connectionStrings");
        foreach (ConnectionStringSettings connectionString in ConfigurationManager.ConnectionStrings)
        {
            var newConnectionString = GetSetting(connectionString.Name);
            if (!string.IsNullOrWhiteSpace(newConnectionString))
            {
                section.ConnectionStrings[connectionString.Name].ConnectionString = newConnectionString;
            }
        }
        configuration.Save(ConfigurationSaveMode.Full);
        ConfigurationManager.RefreshSection(configuration.ConnectionStrings.SectionInformation.Name);
    }

GetSetting() just retrieves the connection string from the setting database.

My app.config looks something like this:

  <connectionStrings>
<add name="SettingsContainer" connectionString="metadata=res://*/EntityFramework.ABC.csdl|res://*/EntityFramework.ABC.ssdl|res://*/EntityFramework.ABC.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=ASERVER;initial catalog=ABC;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework&quot;" providerName="System.Data.EntityClient" />

<add name="AdditionalEntityFrameworkModel" connectionString="" providerName="System.Data.EntityClient" /></connectionStrings>

Any suggestions? Everything is single threaded. Only thing I can think of is that the app.config is loaded into memory at startup and calling Save() and RefreshSection() doesn't update the in memory version, only the file on disk.

Tom
  • 679
  • 1
  • 6
  • 15
  • 1
    Writing to `exe.config` (at runtime) is not a common pattern I see. How did you come to consider trying that as an option? Did you read something recommending it, for example? How are you updating it (something like https://stackoverflow.com/a/5468717/34092 ? something else?)? – mjwills Sep 07 '18 at 13:26
  • My supplied example shows how I'm updating the app.config. The purpose is to be able to deploy the application to different environments without having to manually configure the app.config post deploy. Simplified example: Application starts, connects to settings database and retrieves all settings where application and machine name match. This combination could correspond to dev/uat/live etc – Tom Sep 07 '18 at 13:35

0 Answers0