Udostępnij przez


Wykonywanie operacji wsadowych za pomocą DataAdapters

Obsługa usługi Batch w ADO.NET umożliwia DataAdapter grupowanie operacji INSERT, UPDATE i DELETE z serwera DataSet lub DataTable , zamiast wysyłać jedną operację naraz. Zmniejszenie liczby żądań do serwera zwykle powoduje znaczne poprawy wydajności. Aktualizacje usługi Batch są obsługiwane dla dostawców danych platformy .NET dla programów SQL Server (System.Data.SqlClient) i Oracle (System.Data.OracleClient).

Podczas aktualizowania bazy danych ze zmianami z DataSet w poprzednich wersjach ADO.NET, metoda Update w DataAdapter aktualizowała bazę danych po jednym wierszu naraz. Podczas iteracji wierszy w określonym DataTable obiekcie sprawdzał każdy DataRow, aby zobaczyć, czy został zmodyfikowany. Jeśli wiersz został zmodyfikowany, wywołał odpowiednią UpdateCommand, InsertCommand lub DeleteCommand, w zależności od wartości właściwości RowState dla tego wiersza. Każda aktualizacja wiersza obejmowała połączenie sieciowe z bazą danych.

Począwszy od ADO.NET 2.0, DbDataAdapter uwidacznia właściwość UpdateBatchSize. Ustawienie UpdateBatchSize na dodatnią wartość całkowitą powoduje, że aktualizacje bazy danych są wysyłane jako partie o określonym rozmiarze. Na przykład ustawienie wartości UpdateBatchSize na 10 spowoduje zgrupowanie 10 oddzielnych instrukcji i przesłanie ich jako pojedynczą partię. Ustawienie UpdateBatchSize na 0 spowoduje, że DataAdapter użyje największego rozmiaru paczek, który serwer może obsłużyć. Ustawienie wartości 1 powoduje wyłączenie aktualizacji wsadowych, ponieważ wiersze są wysyłane pojedynczo.

Wykonanie bardzo dużej partii może zmniejszyć wydajność. W związku z tym należy przetestować optymalne ustawienie rozmiaru partii przed wdrożeniem aplikacji.

Używanie właściwości UpdateBatchSize

Po włączeniu aktualizacji wsadowych wartość właściwości elementów DataAdapter `UpdateCommand`, `InsertCommand`, i `DeleteCommand` powinna być ustawiona na `None` lub `OutputParameters`. Podczas przeprowadzania aktualizacji wsadowej wartość UpdatedRowSource właściwości polecenia FirstReturnedRecord lub Both jest nieprawidłowa.

Poniższa procedura przedstawia użycie UpdateBatchSize właściwości . Procedura przyjmuje dwa argumenty: obiekt DataSet, który zawiera kolumny reprezentujące pola ProductCategoryID i Name w tabeli Production.ProductCategory, oraz liczbę całkowitą określającą rozmiar partii (liczbę wierszy w partii). Kod tworzy nowy SqlDataAdapter obiekt, ustawiając jego UpdateCommandwłaściwości , InsertCommandi DeleteCommand . W kodzie przyjęto założenie, że DataSet obiekt zmodyfikował wiersze. Ustawia UpdateBatchSize właściwość i wykonuje aktualizację.

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);
    }
}

Ma DataAdapter dwa zdarzenia związane z aktualizacją: RowUpdating oraz RowUpdated. W poprzednich wersjach ADO.NET, gdy przetwarzanie wsadowe jest wyłączone, każde z tych zdarzeń jest generowane raz dla każdego przetworzonego wiersza. RowUpdating jest generowany przed rozpoczęciem aktualizacji i RowUpdated jest generowany po zakończeniu aktualizacji bazy danych.

Zmiany zachowania zdarzeń za pomocą aktualizacji usługi Batch

Po włączeniu przetwarzania wsadowego wiele wierszy jest aktualizowanych w ramach jednej operacji bazy danych. W związku z tym tylko jedno RowUpdated zdarzenie występuje dla każdej partii, podczas gdy RowUpdating zdarzenie występuje dla każdego przetworzonego wiersza. Gdy przetwarzanie wsadowe jest wyłączone, dwa zdarzenia są wyzwalane za pomocą przeplatania jeden do jednego, gdzie jedno RowUpdating zdarzenie i jedno RowUpdated zdarzenie jest uruchamiane dla wiersza, a następnie jedno RowUpdatingRowUpdated zdarzenie jest uruchamiane dla następnego wiersza, aż wszystkie wiersze zostaną przetworzone.

Uzyskiwanie dostępu do zaktualizowanych wierszy

Po wyłączeniu przetwarzania wsadowego można uzyskać dostęp do wiersza aktualizowanego Row, korzystając z właściwości klasy RowUpdatedEventArgs.

Po włączeniu przetwarzania wsadowego generowane jest pojedyncze zdarzenie RowUpdated dla wielu wierszy. W związku z tym wartość Row właściwości dla każdego wiersza ma wartość null. RowUpdating zdarzenia są nadal generowane dla każdego wiersza. CopyToRows Metoda RowUpdatedEventArgs klasy umożliwia dostęp do przetworzonych wierszy przez skopiowanie odwołań do wierszy do tablicy. Jeśli nie są przetwarzane żadne wiersze, CopyToRows zgłasza błąd ArgumentNullException. Użyj właściwości , RowCount aby zwrócić liczbę przetworzonych wierszy przed wywołaniem CopyToRows metody .

Obsługa błędów danych

Wykonywanie wsadowe ma taki sam efekt jak wykonanie każdej instrukcji. Instrukcje są wykonywane w kolejności dodania do partii. Błędy są obsługiwane w taki sam sposób w trybie wsadowym, jak w przypadku wyłączenia trybu wsadowego. Każdy wiersz jest przetwarzany oddzielnie. Tylko wiersze, które zostały pomyślnie przetworzone w bazie danych, zostaną zaktualizowane w odpowiadających im elementach DataRow w ramach DataTable.

Dostawca danych i serwer bazy danych w zapleczu określają, które wyrażenia SQL są obsługiwane do wykonywania wsadowego. Wyjątek może zostać zgłoszony, jeśli do wykonania zostanie przesłana instrukcja nieobsługiwana.

Zobacz też