VS2005 TableAdapterのConnectionString取得の動作

.NET2.0のテーブルアダプタ便利ですね。
さっそく使われている方も多いと思います。
テーブルアダプタのConnectionStringの取得の動きで注意すべき点があるのでメモっときます。

まずは適当なデータベースのテーブルからデータセットとテーブルアダプタを作成しましょう。
たとえばTestDataSet.xsdというデータセットを作成すると、
一緒に「TestDataSet.Designer.cs」というファイルが作成されます。

このファイル内に自動生成されたテーブルアダプタのコードが入ります。
で、その中にテーブルアダプタの接続初期化メソッドがあります。

■ TestDataSet.Designer.cs

[System.Diagnostics.DebuggerNonUserCodeAttribute()]
private void InitConnection() {
    this._connection = new System.Data.SqlClient.SqlConnection();
    this._connection.ConnectionString = global::[プロジェクト名].Properties.Settings.Default.AdventureWorksConnectionString;
}

不思議なコードですね。

global::[プロジェクト名].Properties.Settings.Default.AdventureWorksConnectionString;

って、何??
疑問に思って調べてみました。
データセットを作成したVSプロジェクトのProperties\Settings.Designer.csファイルを調べてみると、
構成ファイルからConnectionStringを取得しているコードがありました。

■ Settings.Designer.cs

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
        
    private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
        
    public static Settings Default {
        get {
            return defaultInstance;
        }
    }
        
    [global::System.Configuration.ApplicationScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
    [global::System.Configuration.DefaultSettingValueAttribute("Data Source=localhost;Initial Catalog=AdventureWorks;Integrated Security=True")]
    public string AdventureWorksConnectionString {
        get {
            return ((string)(this["AdventureWorksConnectionString"]));
        }
    }
}

スルーしそうになりましたが、以下の一文。

    [global::System.Configuration.DefaultSettingValueAttribute("Data Source=localhost;Initial Catalog=AdventureWorks;Integrated Security=True")]

接続文字列を取得するプロパティに、デフォルト値として接続文字列を設定する属性が...
調べてみると、テーブルアダプタの接続文字列は、デフォルトで構成ファイルが使用され、
構成ファイル(App.config)、Settings.settings、Settings.Designer.csの3箇所に情報が埋め込まれます。
うひゃー、気持ち悪いなぁこの仕組み。
(ちなみに構成ファイルを使わずにテーブルアダプタを構成すると、
テーブルアダプタのコード中に接続文字列が埋め込まれます)

試しに、プロジェクトの構成ファイルの拡張子を変更して実行してみると、
普通にデータベースに接続され実行できます。
アセンブリに上記の属性情報が埋め込まれ、その接続文字列を使用して動いているようですね。。。(x_x

何が問題かというと、開発環境から本番環境に作成したアプリを配置する際に、
上記の仕組みが問題になる場合があります。開発環境の接続情報が埋め込まれるわけですから。
特に、データセットをクラスライブラリプロジェクトに作成し、他のプロジェクトから参照している場合はご注意を。
構成ファイルが正しく読み込まれないと、思いもよらないデータベースに接続しようとします。

解決策?自動生成されるコードを書き換えてもしょうがないので、
「構成ファイルが正しく読み込まれるようにする」しか現状思い浮かびません。。。
何か良いアイデアありましたらお知らせください。