3

update ストアド プロシージャを実行して、テーブル内の 2 つの列だけを更新したいと考えています (このテーブルには他にも多くの列があります)。

現在、私は次のように実装しています-

foreach (Object obj in customCollection)
{
    string[] updatedValues = GetUpdatedValues(obj.Property1);

    using (SqlConnection sqlConnection = new SqlConnection(connString))
    {
         sqlConnection.Open();

         SqlParameter[] sqlParams = new SqlParameter[2];
         sqlParams[0] = new SqlParameter("@column1", SqlDbType.Float) { Value = updatedValues[0]};
         sqlParams[1] = new SqlParameter("@column2", SqlDbType.Float) { Value = updatedValues[1] };

         using (SqlCommand command = new SqlCommand("upUpdateProcedure", sqlConnection))
         {
              command.CommandType = CommandType.StoredProcedure;
              command.Parameters.AddRange(sqlParams);
              DatabaseHelper.ExecuteNonQuery(command);
         }
    }
}

したがって、上記のコードは、コレクション内の各オブジェクトに対してデータベースを呼び出しています。

「C# から SQL Server へのバッチ更新」のリンクをいくつか参照しましたが、これらのリンクのほとんどは、C# コード内でテーブルをロードし、テーブルの行を更新してから、DataAdapter.Update() を呼び出すことを提案しています。

ただし、このシナリオを別の方法で処理する他の既知の方法があるかどうか疑問に思っています。つまり、他の多くの列データも持っているため、テーブル全体をメモリにロードしたくないということです。

ガイドしてください。

4

5 に答える 5

3

私がよく行うことの 1 つは、XML を 1 つのチャンクで SQL に送信することです。ループ内で DB を数回呼び出すよりもはるかに優れたパフォーマンスを発揮します。

ジョン・ギャロウェイには古き良きものがありますが、ここで参照できる良いものがあります。

データまたは列を XML に変換するだけです。クラスにこのデータがある場合、それは本当に簡単です。この拡張メソッドを確認してください。このコードを見つけた場所を覚えていないため、適切に属性を付けることができませんでした。

于 2011-11-29T22:34:54.220 に答える
2

SQLServer 2008以降を使用している場合は、DataTableにデータを入力し、それをテーブル値パラメーターとしてストアドプロシージャに渡すことができます。

テーブル値パラメーターに関する情報:http: //www.sommarskog.se/arrays-in-sql-2008.html#TVP_in_TSQL

ストアドプロシージャは、テーブル変数のようにテーブルパラメータにアクセスできるため、1つのチャンクで更新を実行できます。これは、パフォーマンスに優れています。

このアプローチはBillyCooverのXMLアプローチに似ていますが、XMLの代わりにDataTableを使用します。

于 2011-11-29T23:23:11.403 に答える
0

はい、SQLクエリを動的に構築します。そうです。ストアドプロシージャと比較してパフォーマンスが悪いことはわかっていますが、コード内のすべての接続のオープンとクローズのオーバーヘッドを考慮すると、悪い考えではないかもしれません。また、コードで接続をできるだけ早く開閉しようとしていることにも気づきました。これは良い習慣です。ただし、複数の更新のために1つの接続を開いたままにしておくと、接続を複数回開いたり閉じたりするよりもはるかに高速であることがわかります。ただし、接続を開いたままにしているため、スケーリングはそれほど良くない可能性があります。

于 2011-11-29T22:43:01.297 に答える
0

TableAdapter から DataTable を取得します (自動生成):

FooTableAdaptor tableAdapter = new FooTableAdapter();
FooDataTable dataTable = FooTableAdaptor.MyQuery(...);

変更を行う DataTable の行をスクロールします - これは単なるローカルです。
電話

tableAdapter.Update(dataTable)  

変更を 1 ヒットで書き込みます。

于 2011-11-30T00:30:35.507 に答える
0

あなたがしていることはうまくいくはずです。または、更新の「バッチ」(それぞれ 50、100、またはそれ以上の更新) を作成し、それらをすべてチャンクで送信することもできますが、それがパフォーマンスにまったく役立つかどうかはわかりませんし、おそらく読みにくくなります。

パフォーマンスに問題がありますか? customCollection にはいくつの項目がありますか?

于 2011-11-29T22:28:42.577 に答える