web-dev-qa-db-ja.com

C#データ接続のベストプラクティス?

わかりました。これはそうした意見の多いトピックの1つですが、あなたの知識、意見、および現在の実践に基づいて、次のシナリオを設定する最良の方法は何ですか?

私は大規模なデータ入力アプリケーションを構築しています。大まかに言えば、プログラム全体の約15-25%を組み込んだ基本セットアップしか持っておらず、部分的にセットアップされた約15のフォームがあります。 (まだ作業が必要です)私はSQL Compact 4.0をバックエンドデータベースとして使用しています。MMOに相当するデータを保存していないので、これ以上ローカルデータベースは必要ありません。現時点では、これはローカルアプリケーションのみです。 。

メニューシステムに基づいてさまざまなページに切り替わる単一のウィンドウとして表示されるように設定できるようにしたいのですが、それがどのように達成されるかについての良いチュートリアルを見つけることができないようです。誰もが知っていることを教えてください。

ただし、問題のシナリオは、データベースへの接続方法です。私は2つのSQLCEデータベースを使用しています。1つはサービスとスタッフに基づく一定のデータを格納し、もう1つは最初のデータベースに基づいて入力される絶えず変化するデータまたは新しいデータを格納します。これを設定する方法について多くの異なる方法を見てきましたが、現在、他のすべてのフォームが継承するBaseFormを使用する方法を使用しています。 BaseForm内には、多くのフォームに共通のメソッドと変数があり、繰り返されるコードの量を最小限に抑えています。

これには、両方のデータベースへの接続文字列と、どちらかのデータベースへの接続を開く2つのメソッドが含まれます。そのようです:

internal SqlCeConnection dataConn = new SqlCeConnection(@"Data Source = |DataDirectory|\opi_data.sdf");
internal SqlCeConnection logConn = new SqlCeConnection(@"Data Source = |DataDirectory|\opi_logs.sdf");
internal SqlCeCommand command;

internal void openDataConnection() // Opens a connection to the data tables 
        {
            try
            {
                if(dataConn.State == ConnectionState.Closed)
                    dataConn.Open();
            }
            catch(SqlCeException ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        internal void openLogConnection() // Opens a connection to the log tables
        {
            try
            {
                if(logConn.State == ConnectionState.Closed)
                    logConn.Open();
            }
            catch (SqlCeException ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

次に、オープン接続が必要なときはいつでも、アクセスする必要があるデータベースに対応するオープン接続メソッドを呼び出し、finallyステートメントでそれを閉じます。このようにして、必要なときにだけ、接続が長時間開かれることはありません。もちろん、これは開いている接続メソッドへの呼び出しがたくさんあることを意味します。これは、この種のシナリオを実装する最良の方法ですか、それとももっと良い方法がありますか?

フォームが読み込まれたらすぐに接続を開き、フォームが閉じたら閉じます。一度に複数のフォームが開いているインスタンスがあり、それぞれがおそらくデータベースへの開いた接続を必要とするので、1つを閉じると、他のフォームが正しくねじ込まれるでしょうか?または、アプリケーションの起動時に両方のデータベースへの接続を開く必要がありますか?任意の入力をいただければ幸いです。ありがとう。

22
Josh C.

接続は.NETによってプールされるため、通常、接続の再作成はコストのかかる操作ではありません。ただし、接続を長期間開いたままにしておくと、問題が発生する可能性があります。

ほとんどの「ベストプラクティス」では、できるだけ遅く(SQLを実行する直前)に接続を開き、できるだけ早く(データの最後のビットが抽出された直後に)接続を閉じるように指示しています。

これを自動的に行う効果的な方法は、usingステートメントを使用することです。

using (SqlConnection conn = new SqlConnection(...))
{
    using(SqlCommand cmd = new SqlCommand(..., conn))
    {
        conn.Open();
        using(DataReader dr = cmd.ExecuteReader())  // or load a DataTable, ExecuteScalar, etc.    
        {
             ...
        {
    }
}

これにより、例外がスローされた場合でも、リソースが閉じられて破棄されます。

つまり、アプリが開いたとき、または各フォームが開いたときに接続を開くことは、おそらく最善の方法ではありません。

68
D Stanley