При нескольких изменениях ConfigurationManager не удается обновить DbContext

#c# #entity-framework #connection-string #dbcontext #configurationmanager

#c# #entity-framework #строка подключения #DbContext #ConfigurationManager

Вопрос:

Краткая версия:

Мне нужно перебрать три разные строки подключения в одном приложении winforms (DEV, LIVE и DEMO). Я использую ConfigurationManager для обновления базовой строки подключения. Это работает. Однако мой DbContext учитывает только первое изменение строки подключения. Остальные игнорируются.

Подробные сведения:

Все эти базы данных были созданы сначала с использованием кода, используя один и тот же контекст.

У меня есть единственная строка подключения в моем App.config с именем MY_DB.

Вот основной цикл:

 // Get the necessary Config values
string DEFAULT_DB = "MY_DB";
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConnectionStringsSection csSection = config.ConnectionStrings;
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.ConnectionString = csSection.ConnectionStrings[DEFAULT_DB].ConnectionString;
string provider = csSection.ConnectionStrings[DEFAULT_DB].ProviderName;

System.Diagnostics.Debug.WriteLine(String.Format("Initial: {0}", builder["Initial Catalog"]));


// Loop through my databases
string[] catalogArray = { "live", "demo", "dev" };

foreach (string catalog in catalogArray)
{
    builder["Initial Catalog"] = catalog;
    config.ConnectionStrings.ConnectionStrings.Remove(DEFAULT_DB);
    config.ConnectionStrings.ConnectionStrings.Add(new ConnectionStringSettings(DEFAULT_DB, builder.ConnectionString, provider));
    config.ConnectionStrings.SectionInformation.ForceSave = true;
    config.Save(ConfigurationSaveMode.Full);

    // Tried both of these. Same results.
    // ConfigurationManager.RefreshSection("configuration");
    ConfigurationManager.RefreshSection("connectionStrings");

    System.Diagnostics.Debug.WriteLine(String.Format("Processing: {0}", csSection.ConnectionStrings[DEFAULT_DB].ConnectionString));

    DoDBStuff();

    // Also tried this. No joy.
    // System.GC.Collect();
}
  

Вот DoDBStuff:

 public void DoDBStuff()
    {
        using (MyContext db = new MyContext())
        {
            string connstr = db.Database.Connection.ConnectionString;
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connstr);
            string context = builder.InitialCatalog;
            System.Diagnostics.Debug.WriteLine(String.Format("DoDBStuff is Using: {0}", context));
        }
    }
  

Вот результат (очищенный):

 /*
Initial: dev
Processing: Data Source=1.2.3.4;Initial Catalog=live;User ID=nope;Password=supersecure;MultipleActiveResultSets=True
DoDBStuff is Using: live
Processing: Data Source=1.2.3.4;Initial Catalog=demo;User ID=nope;Password=supersecure;MultipleActiveResultSets=True
DoDBStuff is Using: live
Processing: Data Source=1.2.3.4;Initial Catalog=dev;User ID=nope;Password=supersecure;MultipleActiveResultSets=True
DoDBStuff is Using: live
*/
  

Итак, дорогие переполнители, почему приложение настаивает на использовании только первой конфигурации ‘override’ и игнорирует остальные?

Кстати, я хорошо знаю, что могу сделать что-то подобное:

 MyContext db = new MyContext("CONNECTION_STRING_NAME");
  

Я не хочу этого делать. В основном из-за множества статических методов, которые я вызываю, которые имеют собственное внутреннее использование. Вот так…

 public static Customer ById(int id)
    {
        try
        {
            using (MyContext db = new MyContext())
            {
                return db.Customer.Find(id);
            }
        }
        catch
        {
            return null;
        }
    }
  

Их слишком много, чтобы переопределить их все.

Помогите!