Zusammenführen von DataSet-InhaltenMerging DataSet Contents

Sie können die Merge-Methode verwenden, um den Inhalt eines DataSet-, DataTable- oder DataRow-Arrays in einem vorhandenen DataSet zusammenzuführen.You can use the Merge method to merge the contents of a DataSet, DataTable, or DataRow array into an existing DataSet. Wie die neuen Daten in einem vorhandenen DataSet zusammengeführt werden, hängt von mehreren Faktoren und Optionen ab.Several factors and options affect how new data is merged into an existing DataSet.

PrimärschlüsselPrimary Keys

Wenn die Tabelle, die neue Daten und Schemas aus einem Merge empfängt, einen Primärschlüssel besitzt, werden die neuen Zeilen aus den empfangenen Daten mit vorhandenen Zeilen verglichen, die dieselben Original-Primärschlüsselwerte besitzen wie die empfangenen Daten.If the table receiving new data and schema from a merge has a primary key, new rows from the incoming data are matched with existing rows that have the same Original primary key values as those in the incoming data. Wenn die Spalten aus dem empfangenen Schema mit denen des vorhandenen Schemas übereinstimmen, werden die Daten in den vorhandenen Zeilen geändert.If the columns from the incoming schema match those of the existing schema, the data in the existing rows is modified. Spalten, die nicht mit dem vorhandenen Schema übereinstimmen, werden, abhängig vom Wert des MissingSchemaAction-Parameters, entweder ignoriert oder hinzugefügt.Columns that do not match the existing schema are either ignored or added based on the MissingSchemaAction parameter. Neue Zeilen mit Primärschlüsselwerten, die nicht mit vorhandenen Zeilen übereinstimmen, werden an die vorhandene Tabelle angehängt.New rows with primary key values that do not match any existing rows are appended to the existing table.

Wenn empfangene oder vorhandene Zeilen den Zeilenstatus Added aufweisen, werden ihre Primärschlüsselwerte mit dem Current-Primärschlüsselwert der Added-Zeile verglichen, weil es keine Original-Zeilenversion gibt.If incoming or existing rows have a row state of Added, their primary key values are matched using the Current primary key value of the Added row because no Original row version exists.

Wenn eine empfangene Tabelle und eine vorhandene Tabelle eine Spalte mit demselben Namen, aber unterschiedlichen Datentypen enthalten, wird eine Ausnahme generiert, und das MergeFailed-Ereignis des DataSet wird ausgelöst.If an incoming table and an existing table contain a column with the same name but different data types, an exception is thrown and the MergeFailed event of the DataSet is raised. Wenn sowohl eine empfangene Tabelle als auch eine vorhandene Tabelle definierte Primärschlüssel besitzen, die Primärschlüssel aber für verschiedene Spalten gelten, wird eine Ausnahme generiert und das MergeFailed-Ereignis des DataSet ausgelöst.If an incoming table and an existing table both have defined keys, but the primary keys are for different columns, an exception is thrown and the MergeFailed event of the DataSet is raised.

Wenn die Tabelle, die neue Daten aus einer Zusammenführung empfängt, keinen Primärschlüssel besitzt, können die neuen Zeilen aus den empfangenen Daten nicht mit vorhandenen Zeilen in der Tabelle verglichen werden. Die Zeilen werden dann stattdessen an die vorhandene Tabelle angehängt.If the table receiving new data from a merge does not have a primary key, new rows from the incoming data cannot be matched to existing rows in the table and are instead appended to the existing table.

Tabellennamen und NamespacesTable Names and Namespaces

DataTable-Objekten kann optional ein Namespace-Eigenschaftswert zugewiesen werden.DataTable objects can optionally be assigned a Namespace property value. Wenn Namespace-Werte zugewiesen werden, kann ein DataSet mehrere DataTable-Objekte mit demselben TableName-Wert enthalten.When Namespace values are assigned, a DataSet can contain multiple DataTable objects with the same TableName value. Bei Merges werden sowohl der TableName als auch der Namespace verwendet, um das Ziel des Merge anzugeben.During merge operations, both TableName and Namespace are used to identify the target of a merge. Wenn kein Namespace zugewiesen wurde, wird zur Angabe des Ziels nur der TableName verwendet.If no Namespace has been assigned, only the TableName is used to identify the target of a merge.

Hinweis

Dieses Verhalten ist in .NET Framework 2.0 neu.This behavior changed in version 2.0 of the .NET Framework. In Version 1.1 wurden Namespaces zwar unterstützt, bei Merges wurden sie aber ignoriert.In version 1.1, namespaces were supported but were ignored during merge operations. Aus diesem Grund hängt das Verhalten eines DataSet, das Namespace-Eigenschaftswerte verwendet, von der jeweils verwendeten .NET Framework-Version ab.For this reason, a DataSet that uses Namespace property values will have different behaviors depending on which version of the .NET Framework you are running. Nehmen wir z. B. an, es gibt zwei DataSets, die DataTables mit identischen TableName-Eigenschaftswerten, aber verschiedenen Namespace-Eigenschaftswerten enthalten.For example, suppose you have two DataSets containing DataTables with the same TableName property values but different Namespace property values. In .NET Framework 1.1 werden die verschiedenen Namespace-Namen beim Zusammenführen der beiden DataSet-Objekte ignoriert.In version 1.1 of the .NET Framework, the different Namespace names will be ignored when merging the two DataSet objects. Ab Version 2.0 hingegen werden beim Zusammenführen zwei neue DataTables im Ziel-DataSet erstellt.However, starting with version 2.0, merging causes two new DataTables to be created in the target DataSet. Auf die ursprünglichen DataTables hat die Zusammenführung keine Auswirkung.The original DataTables will be unaffected by the merge.

PreserveChangesPreserveChanges

Wenn Sie ein DataSet-, ein DataTable- oder ein DataRow-Array an die Merge-Methode übergeben, können Sie mit optionalen Parametern angeben, ob Änderungen im vorhandenen DataSet beibehalten werden sollen und wie die neuen Schemaelemente in den empfangenen Daten zu behandeln sind.When you pass a DataSet, DataTable, or DataRow array to the Merge method, you can include optional parameters that specify whether or not to preserve changes in the existing DataSet, and how to handle new schema elements found in the incoming data. Der erste dieser Parameter nach den empfangenen Daten ist ein Boolean-Flag, PreserveChanges, das angibt, ob die Änderungen im vorhandenen DataSet beibehalten werden sollen.The first of these parameters after the incoming data is a Boolean flag, PreserveChanges, which specifies whether or not to preserve the changes in the existing DataSet. Wenn das PreserveChanges-Flag auf true festgelegt ist, werden vorhandene Werte in der Current-Zeilenversion der vorhandenen Zeile nicht durch die empfangenen Werte überschrieben.If the PreserveChanges flag is set to true, incoming values do not overwrite existing values in the Current row version of the existing row. Wenn das PreserveChanges-Flag auf false festgelegt ist, werden die vorhandenen Werte in der Current-Zeilenversion der vorhandenen Zeile mit den empfangenen Werten überschrieben.If the PreserveChanges flag is set to false, incoming values do overwrite the existing values in the Current row version of the existing row. Wenn für das PreserveChanges-Flag nichts angegeben wird, wird es standardmäßig auf false festgelegt.If the PreserveChanges flag is not specified, it is set to false by default. Weitere Informationen zu Zeilen Versionen finden Sie unter Zeilen Status und Zeilen Versionen.For more information about row versions, see Row States and Row Versions.

Wenn das PreserveChanges-Flag auf true festgelegt ist, werden die Daten der vorhandenen Zeile in der Current-Zeilenversion der vorhandenen Zeile beibehalten, während die Daten aus der Original-Zeilenversion der vorhandenen Zeile durch die Daten aus der Original-Zeilenversion der empfangenen Zeile überschrieben werden.When PreserveChanges is true, the data from the existing row is maintained in the Current row version of the existing row, while the data from the Original row version of the existing row is overwritten with the data from the Original row version of the incoming row. Der RowState der vorhandenen Zeile wird auf Modified festgelegt.The RowState of the existing row is set to Modified. Beachten Sie folgende Ausnahmen:The following exceptions apply:

  • Wenn der RowState der vorhandenen Zeile Deleted lautet, bleibt dieser RowState als Deleted erhalten und wird nicht auf Modified festgelegt.If the existing row has a RowState of Deleted, this RowState remains Deleted and is not set to Modified. In diesem Fall werden die Daten aus der empfangenen Zeile immer noch in der Zeilenversion Original der vorhandenen Zeile gespeichert, wobei die Zeilenversion Original der vorhandenen Zeile überschrieben wird (es sei denn, der RowState der empfangenen Zeile lautet Added).In this case, the data from the incoming row will still be stored in the Original row version of the existing row, overwriting the Original row version of the existing row (unless the incoming row has a RowState of Added).

  • Wenn der RowState der empfangenen Zeile Added lautet, werden die Daten aus der Original-Zeilenversion der vorhandenen Zeile nicht mit den Daten der empfangenen Zeile überschrieben, weil die empfangene Zeile keine Original-Zeilenversion besitzt.If the incoming row has a RowState of Added, the data from the Original row version of the existing row will not be overwritten with data from the incoming row, because the incoming row does not have an Original row version.

Wenn das PreserveChanges-Flag auf false festgelegt ist, werden sowohl die Current-Zeilenversion als auch die Original-Zeilenversion in der vorhandenen Zeile durch die Daten der empfangenen Zeile überschrieben, und der RowState der vorhandenen Zeile wird auf den RowState der empfangenen Zeile festgelegt.When PreserveChanges is false, both the Current and Original row versions in the existing row are overwritten with the data from the incoming row, and the RowState of the existing row is set to the RowState of the incoming row. Beachten Sie folgende Ausnahmen:The following exceptions apply:

  • Wenn die empfangene Zeile den RowState``Unchanged und die vorhandene Zeile den RowState``Modified, Deleted oder Added besitzt, wird der RowState der vorhandenen Zeile auf Modified festgelegt.If the incoming row has a RowState of Unchanged and the existing row has a RowState of Modified, Deleted, or Added, the RowState of the existing row is set to Modified.

  • Wenn die empfangene Zeile den RowState``Added und die vorhandene Zeile den RowState``Unchanged, Modified oder Deleted besitzt, wird der RowState der vorhandenen Zeile auf Modified festgelegt.If the incoming row has a RowState of Added, and the existing row has a RowState of Unchanged, Modified, or Deleted, the RowState of the existing row is set to Modified. Außerdem werden die Daten der Original-Zeilenversion der vorhandenen Zeile nicht durch die Daten der empfangenen Zeile überschrieben, weil die empfangene Zeile keine Original-Zeilenversion besitzt.Also, the data from the Original row version of the existing row is not overwritten with data from the incoming row, because the incoming row does not have an Original row version.

MissingSchemaActionMissingSchemaAction

Mit dem optionalen MissingSchemaAction-Parameter der Merge-Methode können Sie angeben, wie die Merge-Methode Schemaelemente in den empfangenen Daten behandeln soll, die nicht Teil des bestehenden DataSet sind.You can use the optional MissingSchemaAction parameter of the Merge method to specify how Merge will handle schema elements in the incoming data that are not part of the existing DataSet.

Eine Beschreibung der Optionen für MissingSchemaAction finden Sie in der folgenden Tabelle.The following table describes the options for MissingSchemaAction.

MissingSchemaAction-OptionMissingSchemaAction option BeschreibungDescription
Add Fügt dem DataSet die neuen Schemainformationen hinzu und füllt die neuen Spalten mit den empfangenen Werten auf.Add the new schema information to the DataSet and populate the new columns with the incoming values. Dies ist die Standardeinstellung.This is the default.
AddWithKey Fügt dem DataSet die neuen Schema- und Primärschlüsselinformationen hinzu und füllt die neuen Spalten mit den empfangenen Werten auf.Add the new schema and primary key information to the DataSet and populate the new columns with the incoming values.
Error Auslösen einer Ausnahme, wenn nicht übereinstimmende Schemainformationen gefunden werden.Throw an exception if mismatched schema information is encountered.
Ignore Ignorieren der neuen Schemainformationen.Ignore the new schema information.

EinschränkungenConstraints

Bei der Merge-Methode werden Einschränkungen erst überprüft, wenn dem vorhandenen DataSet alle neuen Daten hinzugefügt wurden.With the Merge method, constraints are not checked until all new data has been added to the existing DataSet. Sobald die Daten hinzugefügt wurden, werden die Einschränkungen für die aktuellen Werte im DataSet erzwungen.Once the data has been added, constraints are enforced on the current values in the DataSet. Sie müssen sicherstellen, dass Ihr Code die Behandlung von Ausnahmen ermöglicht, die aufgrund von Einschränkungsverletzungen ausgelöst werden.You must ensure that your code handles any exceptions that might be thrown due to constraint violations.

Nehmen wir einmal an, eine vorhandene Zeile in einem DataSet ist eine Zeile mit dem Unchanged-Zeilenstatus und dem Primärschlüsselwert 1.Consider a case where an existing row in a DataSet is an Unchanged row with a primary key value of 1. Beim Zusammenführen mit einer empfangenen Zeile mit dem Modified-Zeilenstatus und dem Original-Primärschlüsselwert 2 sowie dem Current-Primärschlüsselwert 1 werden die vorhandene Zeile und die empfangene Zeile als nicht übereinstimmend betrachtet, weil die Original-Primärschlüsselwerte unterschiedlich sind.During a merge operation with a Modified incoming row with an Original primary key value of 2 and a Current primary key value of 1, the existing row and the incoming row are not considered matching because the Original primary key values differ. Wenn die Zusammenführung abgeschlossen ist und die Einschränkungen überprüft werden, wird allerdings eine Ausnahme ausgelöst, weil die Current-Primärschlüsselwerte die <legacyBold>Unique</legacyBold>-Einschränkung für die Primärschlüsselspalte verletzen.However, when the merge is completed and constraints are checked, an exception will be thrown because the Current primary key values violate the unique constraint for the primary key column.

Hinweis

Beim Einfügen von Zeilen in Datenbanktabellen mit automatisch inkrementierenden Spalten, z. B. Identitätsspalten, ist es möglich, dass der von der Einfügung zurückgegebene Wert für die Identitätsspalte nicht mit dem Wert im DataSet übereinstimmt, sodass die zurückgegebenen Zeilen nicht zusammengeführt, sondern angefügt werden.When rows are inserted into a database table containing an auto incrementing column such as an identity column, the identity column value returned by the insert may not match the value in the DataSet, causing the returned rows to be appended instead of merged. Weitere Informationen finden Sie unter Abrufen von Identitäts-oderAuto Sequenz Werten.For more information, see Retrieving Identity or Autonumber Values.

Im folgenden Codebeispiel werden zwei DataSet -Objekte mit unterschiedlichen Schemas DataSet in einem zusammen mit den kombinierten Schemas der DataSet beiden eingehenden-Objekte zusammengeführt.The following code example merges two DataSet objects with different schemas into one DataSet with the combined schemas of the two incoming DataSet objects.

using (SqlConnection connection =
           new SqlConnection(connectionString))
{
    SqlDataAdapter adapter = 
        new SqlDataAdapter(
        "SELECT CustomerID, CompanyName FROM dbo.Customers", 
        connection);

    connection.Open();

    DataSet customers = new DataSet();
    adapter.FillSchema(customers, SchemaType.Source, "Customers");
    adapter.Fill(customers, "Customers");

    DataSet orders = new DataSet();
    orders.ReadXml("Orders.xml", XmlReadMode.ReadSchema);
    orders.AcceptChanges();

    customers.Merge(orders, true, MissingSchemaAction.AddWithKey);
Using connection As SqlConnection = New SqlConnection( _
   connectionString)

    Dim adapter As New SqlDataAdapter( _
      "SELECT CustomerID, CompanyName FROM Customers", connection)

    connection.Open()

    Dim customers As New DataSet()
    adapter.FillSchema(customers, SchemaType.Source, "Customers")
    adapter.Fill(customers, "Customers")

    Dim orders As New DataSet()
    orders.ReadXml("Orders.xml", XmlReadMode.ReadSchema)
    orders.AcceptChanges()

    customers.Merge(orders, True, MissingSchemaAction.AddWithKey)
End Using

Im folgenden Codebeispiel gibt es ein vorhandenes DataSet mit Updates, die an einen DataAdapter übergeben werden, der an der Datenquelle verarbeitet werden soll.The following code example takes an existing DataSet with updates and passes those updates to a DataAdapter to be processed at the data source. Die Ergebnisse werden anschließend im ursprünglichen DataSet zusammengeführt.The results are then merged into the original DataSet. Nachdem die Änderungen zurückgewiesen wurden, die zu einem Fehler führten, wird mit AcceptChanges ein Commit für die zusammengeführten Änderungen ausgeführt.After rejecting changes that resulted in an error, the merged changes are committed with AcceptChanges.

DataTable customers = dataSet.Tables["Customers"];

// Make modifications to the Customers table.

// Get changes to the DataSet.
DataSet dataSetChanges = dataSet.GetChanges();

// Add an event handler to handle the errors during Update.
adapter.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);

connection.Open();
adapter.Update(dataSetChanges, "Customers");
connection.Close();

// Merge the updates.
dataSet.Merge(dataSetChanges, true, MissingSchemaAction.Add);

// Reject changes on rows with errors and clear the error.
DataRow[] errRows = dataSet.Tables["Customers"].GetErrors();
foreach (DataRow errRow in errRows)
{
    errRow.RejectChanges();
    errRow.RowError = null;
}

// Commit the changes.
dataSet.AcceptChanges();

Dim customers As DataTable = dataSet.Tables("Customers")

' Make modifications to the Customers table.

' Get changes to the DataSet.
Dim dataSetChanges As DataSet = dataSet.GetChanges()

' Add an event handler to handle the errors during Update.
AddHandler adapter.RowUpdated, New SqlRowUpdatedEventHandler( _
  AddressOf OnRowUpdated)

connection.Open()
adapter.Update(dataSetChanges, "Customers")
connection.Close()

' Merge the updates.
dataSet.Merge(dataSetChanges, True, MissingSchemaAction.Add)

' Reject changes on rows with errors and clear the error.
Dim errRows() As DataRow = dataSet.Tables("Customers").GetErrors()
Dim errRow As DataRow
For Each errRow In errRows
    errRow.RejectChanges()
    errRow.RowError = Nothing
Next

' Commit the changes.
dataSet.AcceptChanges()

protected static void OnRowUpdated(
    object sender, SqlRowUpdatedEventArgs args)
{
    if (args.Status == UpdateStatus.ErrorsOccurred)
    {
        args.Row.RowError = args.Errors.Message;
        args.Status = UpdateStatus.SkipCurrentRow;
    }
}
Private Sub OnRowUpdated( _
    ByVal sender As Object, ByVal args As SqlRowUpdatedEventArgs)
    If args.Status = UpdateStatus.ErrorsOccurred Then
        args.Row.RowError = args.Errors.Message
        args.Status = UpdateStatus.SkipCurrentRow
    End If
End Sub

Siehe auchSee also