none
データセットの接続文字列を変数にするにはどうしたらよいでしょうか? RRS feed

  • 質問

  • データソースでSQL SERVERへの接続設定で接続文字列を設定してデータセットを行う方法ですが、この方法だと値に以下のようになりますが

    Provider=Microsoft.ACE.OLEDB.12.0;Data Source=***********(接続パス)***********

    この接続パスを変数で指定するにはどうすればよいでしょうか?My.settingsに保存しているパスを割り当てたいです。

    接続文字列に指定している名前の種類を(接続文字列)→Stringに変更、スコープをアプリケーション→ユーザーに変更すればReadOnlyでは

    無くなるのでこの値に変数を割り当ててみて接続やりたいことは出来るようになったのですが、

    この方法だとデータセットのデザイナを編集しようとしたときに接続文字列の設定が変わってしまっているため接続文字列設定を元に戻さないとデータセットデザイナを編集出来なくなってしまいます。

    良い方法があれば教えて下さい。

    よろしくお願いします。

    2021年4月7日 7:10

回答

  • 接続文字列はすでに settings.settings に保存されていてユーザーはそれを変更できないので、アプリのユーザーがアプリを実行する際、ユーザーが自分の PC の Access ファイルを自由に選択できるようにしたいということであろうと想像して・・・

    昔作ったアプリの例を紹介しておきます。SQL Server Express のユーザーインスタンスを使った C# のアプリで .mdf ファイルをユーザーが選択できるようにしたものです。

    Visual Studio のデーターソース構成ウィザードを使って型付 DataSet/DataTable + TableAdapter を作ると、自動生成された TableAdapter のコードの中に Connection プロパティが定義されているはずです。C# の場合の例ですが以下のようになります。Access の場合も戻り値の型が OleDbConnection になる以外は同じです。

    internal global::System.Data.SqlClient.SqlConnection Connection {
        get {
            if ((this._connection == null)) {
                this.InitConnection();
            }
            return this._connection;
        }
        set {
            this._connection = value;
            if ((this.Adapter.InsertCommand != null)) {
                this.Adapter.InsertCommand.Connection = value;
            }
            if ((this.Adapter.DeleteCommand != null)) {
                this.Adapter.DeleteCommand.Connection = value;
            }
            if ((this.Adapter.UpdateCommand != null)) {
                this.Adapter.UpdateCommand.Connection = value;
            }
            for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1)) {
                if ((this.CommandCollection[i] != null)) {
                    ((global::System.Data.SqlClient.SqlCommand)(this.CommandCollection[i])).Connection = value;
                }
            }
        }
    }

    その Connection プロパティから SqlConnection (Access の場合は OleDbConnection) オブジェクトを取得して、その ConnectionString プロパティに接続文字列を設定するようにします。以下の例を見てください。

    private void button2_Click(object sender, EventArgs e)
    {
        openFileDialog1.Filter = "Database files (*.mdf)|*.mdf";
        openFileDialog1.FileName = "*.mdf";
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            string connectionString = "Data Source=.\\SQLEXPRESS;" + 
                "AttachDbFilename=" + openFileDialog1.FileName +
                ";Integrated Security=True;Connect Timeout=30;User Instance=True";
    
            // Connection を呼ぶと、_connection が null の時は IntConnection() が呼ばれて
            // SqlConnection に接続文字列がセットされるが、null でないときは(DB ファイル
            // を変更する時は)、IntConnection() は呼ばれないので接続文字列を変更できない。
            // IntConnection() で接続文字列をセットするのはやめて、ここでセットすることにした。
            profileTableAdapter.Connection.ConnectionString = connectionString;
            pathTableAdapter.Connection.ConnectionString = connectionString;
            isConnectionStringSet = true;
        }
    }

    2021年4月8日 1:50

すべての返信

  • Settings.settings ファイルに保存してはいかがですか? どのようにアプリを作ったのか不明ですが、Visual Studio のデータソース構成ウィザードを使って型付 DataSet (.xsd ファイル) を作ると、接続文字列は以下のように自動的に Settings.settings ファイルに保存されるはずです(最終的にはそこから .config ファイルに保存されるのですが)。

    2021年4月7日 8:10
  • 正しいフォーラムを選んで投稿するようお願いします。SQL Server のフォーラムに投稿していますが、話としては C# または VB.NET アプリの範疇のようですし、接続文字列を見ると SQL Server ではなく Access になってます。
    2021年4月7日 8:14
  • ひょっとして、Access とか SQLite のようなファイルベースのデーターベースの話ですか?
    2021年4月7日 12:52
  • プロバイダ Microsoft.ACE.OLEDB.12.0 は、Access/Excel などに接続するためのプロバイダとなりますが、接続先は SQL Server ではなく、Access/Excel になりますでしょうか?

    また、要件としてデータセットを複数用意したくないなどの制約がある感じでしょうか?

    他の方が既にアドバイスされているかと思いますが、My.settings に接続文字列をセットして取得すること自体は、どのようにアプリケーションの実装をされているかは定かではございませんが、実現可能かと思います。

     
    2021年4月7日 14:42
  • OLEDBの接続についての質問だったのでこちらの方に質問しましたが、VB.netの方で質問するべきだったのですね。

    申し訳ありませんでした。にも関わらず返信ありがとうございます。

    接続先はAccessです。

    アプリ側で接続先を自由に選べるようにしたいのですが、

    Visual Studio のデータソース構成ウィザードを使って型付 DataSetを作成しているのでMy.settingsの接続文字列は固定のパスになってしまいます。この固定パスをアプリ側で接続先を自由に選べるようにはどのようにするのが一番良いのかというご相談になります。(ウィザードを使用して作成したMy.settingsの接続文字列は読み取りのみの設定になっているので直接変更できません。。)


    • 編集済み Piggy0078 2021年4月7日 23:31
    2021年4月7日 23:28
  • アプリ側で接続先を自由に選べるようにしたいのですが、

    接続文字列はすでに settings.settings に保存されていてユーザーはそれを変更できないので、アプリのユーザーがアプリを実行する際、ユーザーが自分の PC の Access ファイルを自由に選択できるようにしたいということですか?

    2021年4月7日 23:46
  • Microsoft の管理者の方>

    フォーラムの移動をお願いします。

    2021年4月7日 23:48
  • 接続文字列はすでに settings.settings に保存されていてユーザーはそれを変更できないので、アプリのユーザーがアプリを実行する際、ユーザーが自分の PC の Access ファイルを自由に選択できるようにしたいということであろうと想像して・・・

    昔作ったアプリの例を紹介しておきます。SQL Server Express のユーザーインスタンスを使った C# のアプリで .mdf ファイルをユーザーが選択できるようにしたものです。

    Visual Studio のデーターソース構成ウィザードを使って型付 DataSet/DataTable + TableAdapter を作ると、自動生成された TableAdapter のコードの中に Connection プロパティが定義されているはずです。C# の場合の例ですが以下のようになります。Access の場合も戻り値の型が OleDbConnection になる以外は同じです。

    internal global::System.Data.SqlClient.SqlConnection Connection {
        get {
            if ((this._connection == null)) {
                this.InitConnection();
            }
            return this._connection;
        }
        set {
            this._connection = value;
            if ((this.Adapter.InsertCommand != null)) {
                this.Adapter.InsertCommand.Connection = value;
            }
            if ((this.Adapter.DeleteCommand != null)) {
                this.Adapter.DeleteCommand.Connection = value;
            }
            if ((this.Adapter.UpdateCommand != null)) {
                this.Adapter.UpdateCommand.Connection = value;
            }
            for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1)) {
                if ((this.CommandCollection[i] != null)) {
                    ((global::System.Data.SqlClient.SqlCommand)(this.CommandCollection[i])).Connection = value;
                }
            }
        }
    }

    その Connection プロパティから SqlConnection (Access の場合は OleDbConnection) オブジェクトを取得して、その ConnectionString プロパティに接続文字列を設定するようにします。以下の例を見てください。

    private void button2_Click(object sender, EventArgs e)
    {
        openFileDialog1.Filter = "Database files (*.mdf)|*.mdf";
        openFileDialog1.FileName = "*.mdf";
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            string connectionString = "Data Source=.\\SQLEXPRESS;" + 
                "AttachDbFilename=" + openFileDialog1.FileName +
                ";Integrated Security=True;Connect Timeout=30;User Instance=True";
    
            // Connection を呼ぶと、_connection が null の時は IntConnection() が呼ばれて
            // SqlConnection に接続文字列がセットされるが、null でないときは(DB ファイル
            // を変更する時は)、IntConnection() は呼ばれないので接続文字列を変更できない。
            // IntConnection() で接続文字列をセットするのはやめて、ここでセットすることにした。
            profileTableAdapter.Connection.ConnectionString = connectionString;
            pathTableAdapter.Connection.ConnectionString = connectionString;
            isConnectionStringSet = true;
        }
    }

    2021年4月8日 1:50
  • 丁寧な回答ありがとうございます。

    とても勉強になりました。

    参考にソースを変更して自分が想像していたことが出来ました!

    ありがとうございました。

    2021年4月8日 5:19
  • 解決したようですのでこのスレッドはクローズ願います。役に立った回答に「回答としてマーク」を付ければクローズとみなされます。
    2021年4月8日 5:43
  • SurferOnWwwさん、ご確認ありがとうございます。

    Piggy0078さん、こんにちは。フォーラム オペレーターのHarukaです。

    ご質問内容から以下フォーラムのほうが投稿場所として適切かと思いましたので、
    質問の移動をさせていただきました。

    Visual Studio Development  >  Visual C#

    移動後はスレッドの URL が変わりますが以前の URL でもリダイレクトされて、
    以前のページが表示されますのでご安心ください。

    また、SurferOnWwwさんより参考になる投稿が寄せられたようでなによりです。

    [回答としてマーク]機能は設定された投稿が後から参照しやすくなりますので、
    同じ問題でお困りの方のためにも参考になった投稿に設定いただけますと幸いです。

    どうぞよろしくお願いいたします。

    MSDN/ TechNet Community Support Haruka
    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2021年4月9日 0:45
    モデレータ