61

構成ファイル/レジストリキーをまったく変更せずに、プログラムで接続文字列を設定したいと思います。

このコードはありますが、残念ながら「構成は読み取り専用です」という例外がスローされます。

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

編集: 問題は、構成から接続文字列を読み取る既存のコードがあることです。そのため、構成文字列を手動で、またはリソースを介して設定することは、有効なオプションのようには見えません。私が本当に必要としているのは、構成をプログラムで変更する方法です。

4

9 に答える 9

116

これについては、ブログの記事に書いています。秘訣は、リフレクションを使用して、非パブリック フィールド (およびメソッド) へのアクセスを取得する方法として値を突くことです。

例えば。

var settings = ConfigurationManager.ConnectionStrings[ 0 ];

var fi = typeof( ConfigurationElement ).GetField( "_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic );

fi.SetValue(settings, false);

settings.ConnectionString = "Data Source=Something";
于 2008-12-18T11:29:00.747 に答える
9

これにアプローチする別の方法は、コレクションを直接操作することです。

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);
于 2014-07-31T15:41:12.187 に答える
8

ユーザーがクリック ワンス アプリケーションでローカル SQL Server を選択して接続文字列を修正できるようにすることについて、同じ質問に対する答えを探していました。

以下のコードは、ローカルで利用可能なすべての SQL Server に接続し、いずれかを選択できるようにするユーザー フォームを表示します。次に、そのサーバーの接続文字列を作成し、フォームの変数から返します。次に、コードは構成ファイルを修正して保存します。

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))
}
于 2011-09-20T11:06:48.750 に答える
7

これは私にとってうまくいくことがわかりました:

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

これにより、既存の接続文字列が上書きされます。

于 2009-08-21T15:42:01.693 に答える
5

現在、依存性注入を使用して、開発/本番環境とテスト環境で異なる接続文字列を処理しています。dev と prod の間で移動したい場合は、webconfig を手動で変更する必要がありますが、テスト用に、web config を参照するデフォルトの実装と、静的な値を返す別のテスト構成を備えた IConnectionStringFactory インターフェイスがあります。そうすれば、テスト中にファクトリをテスト実装に設定するだけで、要求したキーのテスト接続文字列が返されます。それ以外の場合は、webconfig を調べます。

これを dev と prod の別の実装に拡張することもできますが、IConnectionStringFactory の単一の実装を本番アセンブリに、テスト用の実装をテスト アセンブリに持つ方が快適です。

于 2008-12-11T16:57:48.043 に答える
1

与えられた他の答えに加えて、接続文字列が単に別の構成変数または全体としての定数ではないと仮定すると、文字列を直接連結する代わりにSqlConnectionStringBuilderクラスを使用することを検討できます。

編集:Ups、申し訳ありませんが、基本的に別のソースから接続文字列(完全な私は推測します)を読みたいと思っているのを見ました。

于 2008-12-12T10:10:42.217 に答える
1

代わりにリソースファイルに入れることができます。ConfigurationManager クラスの組み込み機能はありませんが、機能します。

Resources.resx の場合:

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

次に、コードで:

conn.ConnectionString = Resources.Default.ConnectionString

それはハックです、私は知っています。

于 2008-12-11T16:50:49.740 に答える
-1

ConfigurationManager は、構成ファイルから読み取るために使用されます。

あなたの解決策は、単に conn.ConnectionString を必要な conn 文字列に設定することです。

于 2008-12-11T16:55:53.567 に答える