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.
Mit der Merge Methode können Sie den Inhalt eines DataSet, DataTable oder DataRow Arrays in ein bestehendes DataSet
zusammenführen. Mehrere Faktoren und Optionen wirken sich darauf aus, wie neue Daten in einem vorhandenen DataSet
zusammengeführt werden.
Primärschlüssel
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. Wenn die Spalten aus dem eingehenden Schema mit denen des vorhandenen Schemas übereinstimmen, werden die Daten in den vorhandenen Zeilen geändert. Spalten, die nicht mit dem vorhandenen Schema übereinstimmen, werden entweder ignoriert oder basierend auf dem MissingSchemaAction Parameter hinzugefügt. Neue Zeilen mit Primärschlüsselwerten, die keiner vorhandenen Zeile entsprechen, werden an die vorhandene Tabelle angefügt.
Wenn eingehende oder vorhandene Zeilen einen Zeilenstatus Addedaufweisen, werden die Primärschlüsselwerte mit dem Current Primärschlüsselwert der Added
Zeile abgeglichen, da keine Original
Zeilenversion vorhanden ist.
Wenn eine eingehende Tabelle und eine vorhandene Tabelle eine Spalte mit demselben Namen, aber unterschiedliche Datentypen enthalten, wird eine Ausnahme ausgelöst, und das MergeFailed Ereignis der DataSet
Tabelle wird ausgelöst. Wenn eine eingehende Tabelle und eine vorhandene Tabelle beide Schlüssel definiert haben, die Primärschlüssel jedoch für unterschiedliche Spalten gelten, wird eine Ausnahme ausgelöst, und das MergeFailed
Ereignis der DataSet
Tabelle wird ausgelöst.
Wenn die Tabelle, die neue Daten aus einer Datenzusammenführung empfängt, keinen Primärschlüssel aufweist, können neue Zeilen aus den eingehenden Daten nicht mit vorhandenen Zeilen in der Tabelle abgeglichen werden und werden stattdessen an die vorhandene Tabelle angefügt.
Tabellennamen und Namespaces
DataTable Objekten kann optional ein Namespace Eigenschaftswert zugewiesen werden. Wenn Namespace Werten zugewiesen werden, kann ein DataSet Objekt mehrere DataTable Objekte mit demselben TableName Wert enthalten. Bei Zusammenführungsvorgängen werden sowohl TableName als auch Namespace verwendet, um das Ziel einer Zusammenführung zu identifizieren. Wenn kein Namespace zugewiesen wurde, dient nur das TableName dazu, das Ziel einer Zusammenführung zu identifizieren.
Hinweis
Dieses Verhalten wurde in Version 2.0 von .NET Framework geändert. In Version 1.1 wurden Namespaces unterstützt, während der Zusammenführungsvorgänge jedoch ignoriert. Aus diesem Grund kann ein DataSet, das Namespace Eigenschaftswerte verwendet, unterschiedliche Verhaltensmuster aufweisen, je nachdem, welche Version von dem .NET Framework ausgeführt wird. Nehmen wir z. B. an, es gibt zwei DataSets
, die DataTables
mit identischen TableName-Eigenschaftswerten, aber verschiedenen Namespace-Eigenschaftswerten enthalten. In Version 1.1 von .NET Framework werden die verschiedenen Namespace Namen beim Zusammenführen der beiden DataSet Objekte ignoriert. Ab Version 2.0 werden beim Zusammenführen jedoch zwei neue DataTables
im Ziel DataSet erstellt. Das Original DataTables
wird von der Zusammenführung nicht beeinflusst.
PreserveChanges
Wenn Sie ein DataSet
, DataTable
oder DataRow
Array an die Merge
-Methode übergeben, können Sie optionale Parameter angeben, die festlegen, ob Änderungen im vorhandenen DataSet
beibehalten werden sollen und wie neue Schemaelemente behandelt werden, die in den eingehenden Daten gefunden werden. Der erste dieser Parameter nach den eingehenden Daten ist ein boolesches Flag, PreserveChanges, das angibt, ob die Änderungen in der vorhandenen DataSet
erhalten oder nicht erhalten bleiben sollen. Wenn das PreserveChanges
Kennzeichen auf true
festgelegt ist, überschreiben neue Werte keine bestehenden Werte in der Current
-Version der vorhandenen Zeile. Wenn das PreserveChanges
-Flag auf false
festgelegt ist, werden die vorhandenen Werte in der Current
-Zeilenversion der vorhandenen Zeile mit den empfangenen Werten überschrieben. Wenn die PreserveChanges
Flag nicht angegeben ist, wird es standardmäßig auf false
festgelegt. Weitere Informationen zu Zeilenversionen finden Sie unter Zeilenzustände und Zeilenversionen.
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. Die vorhandene Zeile RowState ist auf Modified festgelegt. Beachten Sie folgende Ausnahmen:
Wenn die bestehende Zeile einen
RowState
vonDeleted
hat, bleibtRowState
aufDeleted
bestehen und wird nicht aufModified
gesetzt. In diesem Fall werden die Daten aus der empfangenen Zeile immer noch in der ZeilenversionOriginal
der vorhandenen Zeile gespeichert, wobei die ZeilenversionOriginal
der vorhandenen Zeile überschrieben wird (es sei denn, derRowState
der empfangenen Zeile lautetAdded
).Wenn der
RowState
der empfangenen ZeileAdded
lautet, werden die Daten aus derOriginal
-Zeilenversion der vorhandenen Zeile nicht mit den Daten der empfangenen Zeile überschrieben, weil die empfangene Zeile keineOriginal
-Zeilenversion besitzt.
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. Beachten Sie folgende Ausnahmen:
Wenn die eingehende Zeile eine
RowState
vonUnchanged
hat und die vorhandene Zeile einenRowState
vonModified
,Deleted
oderAdded
besitzt, wird dieRowState
der vorhandenen Zeile aufModified
festgelegt.Wenn die eingehende Zeile eine
RowState
vonAdded
hat und die vorhandene Zeile eineRowState
vonUnchanged
,Modified
oderDeleted
hat, wird dieRowState
der vorhandenen Zeile aufModified
festgelegt. Außerdem werden die Daten aus derOriginal
Zeilenversion der vorhandenen Zeile nicht mit Daten aus der eingehenden Zeile überschrieben, da die eingehende Zeile keineOriginal
Zeilenversion enthält.
MissingSchemaAction
Mit dem optionalen MissingSchemaAction Parameter der Merge
Methode können Sie angeben, wie Merge
Schemaelemente in den eingehenden Daten behandelt werden, die nicht Teil der vorhandenen DataSet
Daten sind.
In der folgenden Tabelle sind die Optionen für MissingSchemaAction
beschrieben.
MissingSchemaAction-Option | BESCHREIBUNG |
---|---|
Add | Fügen Sie die neuen Schemainformationen zu DataSet hinzu und füllen Sie die neuen Spalten mit den eingehenden Werten. Dies ist die Standardeinstellung. |
AddWithKey | Fügen Sie die neuen Schema- und Primärschlüsselinformationen zu DataSet hinzu und befüllen Sie die neuen Spalten mit den eingehenden Werten. |
Error | Werfen Sie eine Ausnahme, wenn inkongruente Schemainformationen gefunden werden. |
Ignore | Ignorieren Sie die neuen Schemainformationen. |
Zwänge
Mit der Merge
Methode werden Einschränkungen erst überprüft, wenn alle neuen Daten dem vorhandenen DataSet
hinzugefügt wurden. Mit dem Hinzufügen der Daten werden Einschränkungen für die aktuellen Werte in der DataSet
durchgesetzt. Sie müssen sicherstellen, dass Ihr Code alle möglichen Ausnahmen behandelt, die aufgrund von Einschränkungsverletzungen geworfen werden können.
Betrachten wir den Fall, in dem eine vorhandene Zeile in einer DataSet
eine Unchanged
-Zeile mit einem Primärschlüsselwert von 1 ist. Bei einem Zusammenführungsvorgang mit einer Modified
eingehenden Zeile mit einem Original
Primärschlüsselwert von 2 und einem Current
Primärschlüsselwert von 1 werden die vorhandene Zeile und die eingehende Zeile nicht als übereinstimmend betrachtet, da sich die Original
Primärschlüsselwerte unterscheiden. Wenn die Zusammenführung abgeschlossen ist und Einschränkungen überprüft werden, wird jedoch eine Ausnahme ausgelöst, da die Current
Primärschlüsselwerte gegen die eindeutige Einschränkung für die Primärschlüsselspalte verstoßen.
Hinweis
Wenn Zeilen in eine Datenbanktabelle eingefügt werden, die eine automatische Inkrementierungsspalte wie eine Identitätsspalte enthält, entspricht der vom Einfügen zurückgegebene Identitätsspaltenwert möglicherweise nicht dem Wert in der DataSet
Datenbanktabelle, wodurch die zurückgegebenen Zeilen angefügt werden, anstatt zusammengeführt zu werden. Weitere Informationen finden Sie unter Abrufen von Identitäts- oder Autonummernwerten.
Im folgenden Codebeispiel werden zwei DataSet
Objekte mit unterschiedlichen Schemas in einem DataSet
mit den kombinierten Schemas der beiden eingehenden DataSet
Objekte zusammengeführt.
using (SqlConnection connection =
new(connectionString))
{
SqlDataAdapter adapter =
new(
"SELECT CustomerID, CompanyName FROM dbo.Customers",
connection);
connection.Open();
DataSet customers = new();
adapter.FillSchema(customers, SchemaType.Source, "Customers");
adapter.Fill(customers, "Customers");
DataSet orders = new();
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 wird ein vorhandenes DataSet
mit Updates versehen, und diese Aktualisierungen werden an ein DataAdapter
zur Verarbeitung an der Datenquelle übergeben. Die Ergebnisse werden dann mit dem Original DataSet
zusammengeführt. Nach dem Ablehnen von Änderungen, die zu einem Fehler geführt haben, werden die zusammengeführten Änderungen mit AcceptChanges
festgeschrieben.
DataTable customers = dataSet.Tables["Customers"]!;
// Make modifications to the Customers table.
// Get changes to the DataSet.
DataSet dataSetChanges = dataSet.GetChanges() ?? new();
// Add an event handler to handle the errors during Update.
adapter.RowUpdated += 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