Como faço para definir uma configuração de string de conexão programaticamente em .net?

Eu gostaria de definir uma seqüência de conexão por meio de programação, com absolutamente nenhuma alteração a quaisquer arquivos de configuração / chaves do Registro.

Eu tenho este pedaço de código, mas infelizmente lança uma exceção com “a configuração é somente leitura”.

ConfigurationManager.ConnectionStrings.Clear(); string connectionString = "Server=myserver;Port=8080;Database=my_db;..."; ConnectionStringSettings connectionStringSettings = new ConnectionStringSettings("MyConnectionStringKey", connectionString); ConfigurationManager.ConnectionStrings.Add(connectionStringSettings); 

Edit: O problema é que eu tenho código existente que lê a seqüência de conexão da configuração. Portanto, definir a string de configuração manualmente ou por meio de um recurso não parece ser uma opção válida. O que eu realmente preciso é uma maneira de modificar a configuração programaticamente.

Eu escrevi sobre isso em um post no meu blog . O truque é usar a reflection para inserir os valores de modo a obter access aos campos não públicos (e methods).

por exemplo.

 var settings = ConfigurationManager.ConnectionStrings[ 0 ]; var fi = typeof( ConfigurationElement ).GetField( "_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic ); fi.SetValue(settings, false); settings.ConnectionString = "Data Source=Something"; 

Eu estava procurando a resposta para a mesma qustion sobre permitir que o usuário alterar a seqüência de conexão em um clique uma vez aplicativo, selecionando um SQL Server local.

O código abaixo exibe um formulário de usuário que contata todos os SQL Servers disponíveis localmente e permite que eles selecionem um. Em seguida, ele constrói uma cadeia de conexão para esse servidor e o retorna de uma variável no formulário. O código então altera os arquivos de configuração e economiza.

 string NewConnection = ""; // get the user to supply connection details frmSetSQLConnection frm = new frmSetSQLConnection(); frm.ShowDialog(); if (frm.DialogResult == DialogResult.OK) { // here we set the users connection string for the database // Get the application configuration file. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); // Get the connection strings section. ConnectionStringsSection csSection = config.ConnectionStrings; foreach (ConnectionStringSettings connection3 in csSection.ConnectionStrings) { // Here we check for the preset string - this could be done by item no as well if (connection3.ConnectionString == "Data Source=SQL204\\SQL2008;Initial Catalog=Transition;Integrated Security=True") { // amend the details and save connection3.ConnectionString = frm.Connection; NewConnection = frm.Connection; break; } } config.Save(ConfigurationSaveMode.Modified); // reload the config file so the new values are available ConfigurationManager.RefreshSection(csSection.SectionInformation.Name); return clsDBMaintenance.UpdateDatabase(NewConnection)) } 

Outra maneira de abordar isso seria operar diretamente na coleção:

 var settings = ConfigurationManager.ConnectionStrings; var element = typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); var collection = typeof(ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); element.SetValue(settings, false); collection.SetValue(settings, false); settings.Add(new ConnectionStringSettings("ConnectionStringName", connectionString)); // Repeat above line as necessary collection.SetValue(settings, true); element.SetValue(settings, true); 

Eu acho que isso funciona para mim:

 Configuration config = WebConfigurationManager.OpenWebConfiguration("~"); ConnectionStringsSection section = config.GetSection("connectionStrings") as ConnectionStringsSection; if (section != null) { section.ConnectionStrings["MyConnectionString"].ConnectionString = connectionString; config.Save(); } 

Isso substitui uma string de conexão existente.

Atualmente estou usando injeção de dependência para lidar com diferentes seqüências de conexão em ambientes dev / prod vs. test. Eu ainda tenho que alterar manualmente o webconfig se eu quiser passar para entre dev e prod, mas para testar eu tenho uma interface IConnectionStringFactory com uma implementação padrão que analisa a configuração da web e uma configuração alternativa de teste que retorna valores estáticos. Dessa forma, quando estou testando, simplesmente configuro a fábrica para a implementação de teste e ele retornará a string de conexão de teste para a chave que solicito. Caso contrário, irá procurar no webconfig.

Eu poderia estender isso para outra implementação para dev vs. prod, mas estou mais confortável com uma única implementação de IConnectionStringFactory em meu assembly de produção e a implementação de teste em meu assembly de teste.

Você poderia colocá-lo em um arquivo de resources. Ele não terá os resources internos da class ConfigurationManager, mas funcionará.

Assumindo Resources.resx:

Resources.Default.ConnectionString = "Server=myserver;" // etc

Então, no seu código:

conn.ConnectionString = Resources.Default.ConnectionString

É um hack, eu sei.

Além das outras respostas dadas, e supondo que a cadeia de conexão não seja simplesmente outra variável de configuração ou constante como um todo, você pode considerar o uso da class SqlConnectionStringBuilder em vez de concatenar diretamente a cadeia de caracteres.

EDIT: Ups, desculpe só vi que você basicamente quer ler sua seqüência de conexão (completa, eu acho) de outra fonte.

O ConfigurationManager é usado para ler o arquivo de configuração.

Sua solução é simplesmente configurar conn.ConnectionString para a cadeia de conexões que você precisa.