DataAdapter を使用したバッチ操作の実行Performing Batch Operations Using DataAdapters

ADO.NET のバッチ サポートを利用すると、DataAdapter は、DataSet または DataTable から INSERT、UPDATE、および DELETE の各操作を 1 操作ずつサーバーに送信するのではなく、グループ化してサーバーに送信できます。Batch support in ADO.NET allows a DataAdapter to group INSERT, UPDATE, and DELETE operations from a DataSet or DataTable to the server, instead of sending one operation at a time. こうすることで、サーバーへのラウンド トリップの回数が減少し、大幅なパフォーマンスの向上が期待できます。The reduction in the number of round trips to the server typically results in significant performance gains. バッチ更新は、SQL Server (System.Data.SqlClient) および Oracle (System.Data.OracleClient) の .NET データ プロバイダーでサポートされています。Batch updates are supported for the .NET data providers for SQL Server (System.Data.SqlClient) and Oracle (System.Data.OracleClient).

以前のバージョンの ADO.NET では、DataSet に格納されている変更内容をデータベースに反映する場合、UpdateDataAdapter メソッドを実行して、1 行ずつデータベースを更新していました。When updating a database with changes from a DataSet in previous versions of ADO.NET, the Update method of a DataAdapter performed updates to the database one row at a time. このメソッドは、指定された DataTable 内の行を反復処理すると、各 DataRow を調べ、行が変更されたことを確認します。As it iterated through the rows in the specified DataTable, it examined each DataRow to see if it had been modified. 行が変更されている場合、その行の UpdateCommand プロパティの値に基づいて、適切な InsertCommandDeleteCommand、または RowState のいずれかを呼び出します。If the row had been modified, it called the appropriate UpdateCommand, InsertCommand, or DeleteCommand, depending on the value of the RowState property for that row. 各行の更新では、データベースへのネットワーク ラウンドトリップが発生します。Every row update involved a network round-trip to the database.

ADO.NET 2.0 以降では、DbDataAdapterUpdateBatchSize プロパティを公開します。Starting with ADO.NET 2.0, the DbDataAdapter exposes an UpdateBatchSize property. UpdateBatchSize を正の整数値に設定すると、データベースの更新が指定されたサイズのバッチとして送信されます。Setting the UpdateBatchSize to a positive integer value causes updates to the database to be sent as batches of the specified size. たとえば、UpdateBatchSize を 10 に設定すると、10 個の個別のステートメントがグループ化され、単一のバッチとして送信されます。For example, setting the UpdateBatchSize to 10 will group 10 separate statements and submit them as single batch. UpdateBatchSize を 0 に設定すると、DataAdapter は、サーバーが処理できる最大のバッチ サイズを使用します。Setting the UpdateBatchSize to 0 will cause the DataAdapter to use the largest batch size that the server can handle. 1 に設定すると、バッチ更新が無効になり、1 行ずつ送信されます。Setting it to 1 disables batch updates, as rows are sent one at a time.

サイズの大きいバッチを実行すると、パフォーマンスが低下する可能性があります。Executing an extremely large batch could decrease performance. そのため、アプリケーションを実装する前に、バッチの最適なサイズ設定をテストする必要があります。Therefore, you should test for the optimum batch size setting before implementing your application.

UpdateBatchSize プロパティの使用Using the UpdateBatchSize Property

バッチ更新を有効にする場合、DataAdapter の UpdatedRowSourceUpdateCommand および InsertCommandDeleteCommand プロパティ値を、None または OutputParameters に設定する必要があります。When batch updates are enabled, the UpdatedRowSource property value of the DataAdapter's UpdateCommand, InsertCommand, and DeleteCommand should be set to None or OutputParameters. バッチ更新を実行する際、UpdatedRowSource または FirstReturnedRecord のコマンドの Both プロパティ値は、無効になります。When performing a batch update, the command's UpdatedRowSource property value of FirstReturnedRecord or Both is invalid.

UpdateBatchSize プロパティを使用するプロシージャを次に示します。The following procedure demonstrates the use of the UpdateBatchSize property. このプロシージャは2つの引数DataSetを受け取ります。 このオブジェクトには、 productcategoryidテーブルとNameフィールドを表す列と、バッチサイズを表す整数 (バッチ内の行。The procedure takes two arguments, a DataSet object that has columns representing the ProductCategoryID and Name fields in the Production.ProductCategory table, and an integer representing the batch size (the number of rows in the batch). このコードにより、新しい SqlDataAdapter オブジェクトが作成され、その UpdateCommand プロパティ、InsertCommand プロパティ、および DeleteCommand プロパティが設定されます。The code creates a new SqlDataAdapter object, setting its UpdateCommand, InsertCommand, and DeleteCommand properties. このコードは、DataSet オブジェクトによって行が変更済みになっていることを前提としています。The code assumes that the DataSet object has modified rows. このオブジェクトは、UpdateBatchSize プロパティを設定し、更新を実行します。It sets the UpdateBatchSize property and executes the update.

Public Sub BatchUpdate( _  
  ByVal dataTable As DataTable, ByVal batchSize As Int32)  
    ' Assumes GetConnectionString() returns a valid connection string.  
    Dim connectionString As String = GetConnectionString()  
  
    ' Connect to the AdventureWorks database.  
    Using connection As New SqlConnection(connectionString)  
        ' Create a SqlDataAdapter.  
        Dim adapter As New SqlDataAdapter()  
  
        'Set the UPDATE command and parameters.  
        adapter.UpdateCommand = New SqlCommand( _  
          "UPDATE Production.ProductCategory SET " _  
          & "Name=@Name WHERE ProductCategoryID=@ProdCatID;", _  
          connection)  
        adapter.UpdateCommand.Parameters.Add("@Name", _  
          SqlDbType.NVarChar, 50, "Name")  
        adapter.UpdateCommand.Parameters.Add("@ProdCatID",  _  
          SqlDbType.Int, 4, " ProductCategoryID ")  
        adapter.UpdateCommand.UpdatedRowSource = _  
          UpdateRowSource.None  
  
        'Set the INSERT command and parameter.  
        adapter.InsertCommand = New SqlCommand( _  
          "INSERT INTO Production.ProductCategory (Name) VALUES (@Name);", _  
  connection)  
        adapter.InsertCommand.Parameters.Add("@Name", _  
          SqlDbType.NVarChar, 50, "Name")  
        adapter.InsertCommand.UpdatedRowSource = _  
          UpdateRowSource.None  
  
        'Set the DELETE command and parameter.  
        adapter.DeleteCommand = New SqlCommand( _  
          "DELETE FROM Production.ProductCategory " _  
          & "WHERE ProductCategoryID=@ProdCatID;", connection)  
        adapter.DeleteCommand.Parameters.Add("@ProdCatID", _  
           SqlDbType.Int, 4, " ProductCategoryID ")  
        adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None  
  
        ' Set the batch size.  
        adapter.UpdateBatchSize = batchSize  
  
        ' Execute the update.  
        adapter.Update(dataTable)  
    End Using  
End Sub  
public static void BatchUpdate(DataTable dataTable,Int32 batchSize)  
{  
    // Assumes GetConnectionString() returns a valid connection string.  
    string connectionString = GetConnectionString();  
  
    // Connect to the AdventureWorks database.  
    using (SqlConnection connection = new   
      SqlConnection(connectionString))  
    {  
  
        // Create a SqlDataAdapter.  
        SqlDataAdapter adapter = new SqlDataAdapter();  
  
        // Set the UPDATE command and parameters.  
        adapter.UpdateCommand = new SqlCommand(  
            "UPDATE Production.ProductCategory SET "  
            + "Name=@Name WHERE ProductCategoryID=@ProdCatID;",   
            connection);  
        adapter.UpdateCommand.Parameters.Add("@Name",   
           SqlDbType.NVarChar, 50, "Name");  
        adapter.UpdateCommand.Parameters.Add("@ProdCatID",   
           SqlDbType.Int, 4, "ProductCategoryID");  
         adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;  
  
        // Set the INSERT command and parameter.  
        adapter.InsertCommand = new SqlCommand(  
            "INSERT INTO Production.ProductCategory (Name) VALUES (@Name);",   
            connection);  
        adapter.InsertCommand.Parameters.Add("@Name",   
          SqlDbType.NVarChar, 50, "Name");  
        adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None;  
  
        // Set the DELETE command and parameter.  
        adapter.DeleteCommand = new SqlCommand(  
            "DELETE FROM Production.ProductCategory "  
            + "WHERE ProductCategoryID=@ProdCatID;", connection);  
        adapter.DeleteCommand.Parameters.Add("@ProdCatID",   
          SqlDbType.Int, 4, "ProductCategoryID");  
        adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None;  
  
        // Set the batch size.  
        adapter.UpdateBatchSize = batchSize;  
  
        // Execute the update.  
        adapter.Update(dataTable);  
    }  
}  

DataAdapterには、次の2つの更新関連イベントがあります。RowUpdatingRowUpdatedThe DataAdapter has two update-related events: RowUpdating and RowUpdated. 以前のバージョンの ADO.NET では、バッチ処理が無効になっていると、処理された行ごとにこれらのイベントがそれぞれ生成されます。In previous versions of ADO.NET, when batch processing is disabled, each of these events is generated once for each row processed. RowUpdatingは、更新が行われる前に生成され、データベースの更新が完了した後にRowUpdatedが生成されます。RowUpdating is generated before the update occurs, and RowUpdated is generated after the database update has been completed.

バッチ更新とイベント動作の違いEvent Behavior Changes with Batch Updates

バッチ処理が有効になっている場合、1 度のデータベース操作で複数の行が更新されます。When batch processing is enabled, multiple rows are updated in a single database operation. このため、RowUpdated イベントは処理された各行ごとに発生しますが、RowUpdating イベントは各バッチ処理につき、1 つしか発生しません。Therefore, only one RowUpdated event occurs for each batch, whereas the RowUpdating event occurs for each row processed. バッチ処理が無効になっている場合、1 対 1 のインターリーブを伴う 2 つのイベントが発生します。つまり、1 つの行に対し、RowUpdating イベントが 1 つ、RowUpdated イベントが 1 つ発生します。すべての行が処理されるまで、次の行に対して RowUpdating イベントが 1 つ、RowUpdated イベントが 1 つ発生します。When batch processing is disabled, the two events are fired with one-to-one interleaving, where one RowUpdating event and one RowUpdated event fire for a row, and then one RowUpdating and one RowUpdated event fire for the next row, until all of the rows are processed.

更新された行へのアクセスAccessing Updated Rows

バッチ処理が無効になっている場合、更新された行には、Row クラスの RowUpdatedEventArgs プロパティを使用してアクセスできます。When batch processing is disabled, the row being updated can be accessed using the Row property of the RowUpdatedEventArgs class.

バッチ処理が有効になっている場合、複数の行に対して 1 つの RowUpdated イベントが生成されます。When batch processing is enabled, a single RowUpdated event is generated for multiple rows. つまり、各行の Row プロパティ値は null ですが、Therefore, the value of the Row property for each row is null. RowUpdating イベントは各行に対して生成されます。RowUpdating events are still generated for each row. 処理された行にアクセスするには、CopyToRows クラスの RowUpdatedEventArgs メソッドにより、配列に行への参照をコピーします。The CopyToRows method of the RowUpdatedEventArgs class allows you to access the processed rows by copying references to the rows into an array. 処理される行がない場合、CopyToRowsArgumentNullException をスローします。If no rows are being processed, CopyToRows throws an ArgumentNullException. RowCount メソッドを呼び出す前に、CopyToRows プロパティを使用して、処理されている行数を取得できます。Use the RowCount property to return the number of rows processed before calling the CopyToRows method.

データ エラーの処理Handling Data Errors

ステートメントを個別に実行した場合とバッチ処理を実行した場合では効果は同じです。Batch execution has the same effect as the execution of each individual statement. ステートメントはバッチに追加された順序と同じ順序で実行されます。Statements are executed in the order that the statements were added to the batch. エラーは、バッチ モードでも、バッチ モードが無効な場合と同様に処理されます。Errors are handled the same way in batch mode as they are when batch mode is disabled. つまり、各行が個別に処理されます。Each row is processed separately. データベース内で正常に処理された行だけが、DataRow 内の対応する DataTable で更新されます。Only rows that have been successfully processed in the database will be updated in the corresponding DataRow within the DataTable.

バッチ処理の実行に対してサポートされる SQL 構成は、データ プロバイダーとバックエンド データベースが決定します。The data provider and the back-end database server determine which SQL constructs are supported for batch execution. サポートされていないステートメントが実行時に送信されると、例外がスローされる場合があります。An exception may be thrown if a non-supported statement is submitted for execution.

関連項目See also