Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Durch Batch-Unterstützung in ADO.NET kann ein DataAdapter die Operationen INSERT, UPDATE und DELETE aus einem DataSet oder einer DataTable an einen Server zusammenfassen, anstatt nur jeweils eine Operation senden zu können. Durch das Reduzieren der Anzahl von Roundtrips zum Server kann im Allgemeinen die Leistung beträchtlich gesteigert werden. Batchupdates werden für die .NET-Datenanbieter für SQL Server (System.Data.SqlClient) und Oracle (System.Data.OracleClient) unterstützt.
Beim Aktualisieren einer Datenbank mit Änderungen aus einem DataSet in früheren Versionen von ADO.NET wurde die Datenbank mithilfe der Update-Methode eines DataAdapter zeilenweise, also Reihe für Reihe, aktualisiert. Dabei wurden die Zeilen in der angegebenen DataTable durchlaufen, wobei jede DataRow auf Änderungen geprüft wurde. Wenn die Zeile geändert worden war, wurde der entsprechende UpdateCommand, InsertCommand oder DeleteCommand aufgerufen, abhängig vom Wert der RowState-Eigenschaft für diese Zeile. Für jede Zeilenaktualisierung war ein Netzwerkroundtrip zur Datenbank erforderlich.
Beginnend mit ADO.NET 2.0 wird vom DbDataAdapter-Objekt eine UpdateBatchSize-Eigenschaft verfügbar gemacht. Wenn die UpdateBatchSize-Eigenschaft auf einen positiven ganzzahligen Wert festgelegt wird, werden Updates der Datenbank als Batches mit der angegebenen Größe gesendet. Wenn Sie beispielsweise UpdateBatchSize auf 10 festlegen, werden 10 Anweisungen gruppiert und als ein einzelner Batch gesendet. Wird dagegen für UpdateBatchSize 0 festgelegt, verwendet der DataAdapter die größtmöglichen Batches, die der Server unterstützt. Bei einem Wert von 1 werden Batchupdates deaktiviert, weil die Zeilen einzeln nacheinander gesendet werden.
Die Ausführung eines extrem großen Batches könnte die Leistung verringern. Daher sollten Sie die Einstellung für eine optimale Batchgröße vor der Implementierung Ihrer Anwendung austesten.
Verwenden der "UpdateBatchSize"-Eigenschaft
Wenn Batchupdates aktiviert sind, sollte der UpdatedRowSource-Eigenschaftswert von UpdateCommand, InsertCommand und DeleteCommand des DataAdapter auf None oder OutputParameters festgelegt werden. Beim Durchführen eines Batch-Updates ist der Wert der UpdatedRowSource oder FirstReturnedRecord-Eigenschaft des Befehls ungültig.
In der folgenden Prozedur wird die Verwendung der UpdateBatchSize-Eigenschaft veranschaulicht. Die Prozedur verwendet zwei Argumente, ein DataSet Objekt, das Spalten enthält, die die ProductCategoryID Felder Name in der Tabelle Production.ProductCategory darstellen, und eine ganze Zahl, die die Batchgröße (die Anzahl der Zeilen im Batch) darstellt. Der Code erstellt ein neues SqlDataAdapter-Objekt und legt dessen Eigenschaften UpdateCommand, InsertCommand und DeleteCommand fest. Der Code geht davon aus, dass das DataSet-Objekt geänderte Zeilen aufweist. Er legt einen Wert für die UpdateBatchSize-Eigenschaft fest und führt das Update aus.
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);
}
}
Behandeln von Ereignissen und Fehlern im Zusammenhang mit dem Batchupdate
Dies DataAdapter umfasst zwei updatebezogene Ereignisse: RowUpdating und RowUpdated. In älteren Versionen von ADO.NET werden diese Ereignisse jeweils einmal für jede verarbeitete Zeile generiert, wenn die Batchverarbeitung deaktiviert wurde.
RowUpdating wird generiert, bevor die Aktualisierung erfolgt und RowUpdated nach Abschluss der Datenbankaktualisierung generiert wird.
Änderungen im Ereignisverhalten durch Batchupdates
Bei aktivierter Batchverarbeitung werden mehrere Zeilen in einer einzigen Datenbankoperation aktualisiert. Deshalb findet pro Batch nur ein RowUpdated-Ereignis statt, wohingegen das RowUpdating-Ereignis für jede verarbeitete Zeile auftritt. Bei deaktivierter Batchverarbeitung werden die beiden Ereignisse abwechselnd ausgelöst: Zunächst wird ein RowUpdating-Ereignis und dann ein RowUpdated-Ereignis für eine Zeile ausgelöst. Danach wird ein RowUpdating-Ereignis und ein RowUpdated-Ereignis für die nächste Zeile ausgelöst. Dies setzt sich fort, bis alle Zeilen verarbeitet sind.
Zugreifen auf aktualisierte Zeilen
Bei deaktivierter Batchverarbeitung kann auf die zu aktualisierende Zeile mit der Row-Eigenschaft der RowUpdatedEventArgs-Klasse zugegriffen werden.
Bei aktivierter Batchverarbeitung wird für mehrere Zeilen ein einziges RowUpdated-Ereignis generiert. Daher ist der Wert der Row-Eigenschaft in jeder Zeile NULL. Es werden weiterhin RowUpdating-Ereignisse für jede Zeile generiert. Mit der CopyToRows-Methode der RowUpdatedEventArgs-Klasse können Sie auf die verarbeiteten Zeilen zugreifen, indem Sie Verweise auf die Zeilen in ein Array kopieren. Wenn keine Zeilen verarbeitet werden, löst CopyToRows eine ArgumentNullException aus. Verwenden Sie die RowCount-Eigenschaft, um vor dem Aufruf der CopyToRows-Methode die Anzahl der verarbeiteten Zeilen zurückzugeben.
Behandeln von Datenfehlern
Eine Batchausführung hat dieselben Auswirkungen wie die Ausführung einzelner Anweisungen. Anweisungen werden in der Reihenfolge ausgeführt, in der sie dem Batch hinzugefügt wurden. Fehler werden im Batchmodus in derselben Weise behandelt wie bei deaktiviertem Batchmodus. Jede Zeile wird einzeln verarbeitet. Nur Zeilen, die erfolgreich in der Datenbank verarbeitet wurden, werden in der entsprechenden DataRow innerhalb der DataTable aktualisiert.
Der Datenanbieter und der Back-End-Datenbankserver bestimmen, welche SQL-Konstrukte für die Batchausführung unterstützt werden. Wenn eine nicht unterstützte Anweisung ausgeführt werden soll, wird möglicherweise eine Ausnahme ausgelöst.