Zusammenführen von DataSet-Inhalten
Sie können den Inhalt eines DataSet-Arrays, eines DataTable-Arrays oder eines DataRow-Arrays mit der Merge-Methode des DataSets in einem bestehenden DataSet zusammenführen. Die Art und Weise, in der Daten in einem bestehenden DataSet zusammengeführt werden, wird durch mehrere Faktoren und Optionen beeinflusst.
Primärschlüssel
Wenn die Tabelle, die neue Daten und Schemas aus einer Zusammenführung empfängt, einen Primärschlüssel besitzt, werden die empfangenen Daten mit vorhandenen Zeilen verglichen, die dieselben Original-Primärschlüsselwerte haben wie die empfangenen Daten. Wenn die Spalten aus dem empfangenen Schema mit denen des bestehenden Schemas übereinstimmen, werden die Daten in den vorhandenen Zeilen geändert. Spalten, die nicht mit dem vorhandenen Schema übereinstimmen, werden entweder ignoriert oder auf der Grundlage des MissingSchemaAction-Parameters hinzugefügt (siehe "MissingSchemaAction" weiter unten in diesem Thema). Neue Zeilen mit Primärschlüsselwerten, die nicht mit bestehenden Zeilen übereinstimmen, werden an die vorhandene Tabelle angehängt.
Wenn empfangene oder bestehende Zeilen den Zeilenstatus Added aufweisen, werden die Werte ihrer Primärschlüssel mit dem Current-Primärschlüssel der Added-Zeile verglichen, weil keine Original-Zeilenversion vorhanden ist.
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 DataSets wird ausgelöst. Wenn eine empfangene Tabelle und eine vorhandene Tabelle Primärschlüssel besitzen, die Primärschlüssel aber für verschiedene Spalten gelten, wird eine Ausnahme generiert und das MergeFailed-Ereignis des DataSets ausgelöst.
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.
preserveChanges
Wenn Sie ein DataSet-Array, ein DataTable-Array oder ein DataRow-Array an die Merge-Methode übergeben, können Sie mit optionalen Parametern angeben, ob Änderungen im vorhandenen DataSet beibehalten werden oder nicht; außerdem können Sie festlegen, wie die neuen Schemaelemente der empfangenen Daten behandelt werden. Der erste dieser Parameter nach den empfangenen Daten ist ein Boolean-Flag, preserveChanges, das angibt, ob die Änderungen im vorhandenen DataSet beibehalten werden oder nicht. Wenn für das preserveChanges-Flag True festgelegt ist, werden bestehende Werte in der Current-Zeilenversion der vorhandenen Zeile nicht mit den empfangenen Werten überschrieben. Wenn für das preserveChanges-Flag False festgelegt ist, werden bestehende Werte in der Current-Zeilenversion der vorhandenen Zeile mit den empfangenen Werten überschrieben. Wenn das preserveChanges-Flag nicht angegeben ist, wird standardmäßig False festgelegt. Weitere Informationen zu Zeilenversionen finden Sie unter Zeilenstatus und Zeilenversion.
Wenn für das preserveChanges-Flag True festgelegt ist, werden die Daten der vorhandenen Zeile in der Current-Zeilenversion der bestehenden Zeile beibehalten, während die Daten aus der Original-Zeilenversion der bestehenden Zeile mit den Daten aus der Original-Zeilenversion der empfangenen Zeile überschrieben werden. Für den RowState der bestehenden Zeile wird Modified festgelegt. Beachten Sie folgende Ausnahmen:
- Wenn der RowState der vorhandenen Zeile Deleted lautet, bleibt der RowState erhalten und es wird nicht Modified dafür festgelegt. In diesem Fall werden die Daten aus der empfangenen Zeile immer noch in der Original-Zeilenversion der bestehenden Zeile gespeichert, wobei die Original-Zeilenversion der bestehenden Zeile überschrieben wird (es sei denn, der RowState der empfangenen Zeile lautet Added).
- Wenn der RowState der empfangenen Zeile Added lautet, werden die Daten der Original-Zeilenversion der vorhandenen Zeile nicht mit den Daten der empfangenen Zeile überschrieben, weil die empfangene Zeile keine Original-Zeilenversion besitzt.
Wenn für das preserveChanges-Flag False festgelegt ist, werden die Current-Zeilenversion und die Original-Zeilenversion der vorhanden Zeile mit den Daten der empfangenen Zeile überschrieben, und der RowState der bestehenden Zeile wird auf den RowState der empfangenen Zeile festgelegt. Beachten Sie folgende Ausnahmen:
- Wenn der RowState der empfangenen Zeile Unchanged und der RowState der vorhandenen Zeile Modified, Deleted oder Added lautet, wird für den RowState der bestehenden Zeile Modified festgelegt.
- Wenn der RowState der empfangenen Zeile Added und der RowState der vorhandenen Zeile Unchanged, Modified oder Deleted lautet, wird für den RowState der bestehenden Zeile Modified festgelegt. Außerdem werden die Daten der Original-Zeilenversion der vorhandenen Zeile nicht mit den Daten der empfangenen Zeile überschrieben, weil die empfangene Zeile keine Original-Zeilenversion besitzt.
MissingSchemaAction
Mit dem optionalen MissingSchemaAction-Parameter der Merge-Methode können Sie angeben, wie die Merge-Methode Schemaelemente in den empfangenen Daten behandelt, die nicht Teil des bestehenden DataSets sind.
In der folgenden Tabelle werden die Optionen für MissingSchemaAction beschrieben.
MissingSchemaAction | Beschreibung |
---|---|
Add | Die neuen Schemainformationen zum DataSet hinzufügen und die neuen Spalten mit den empfangenen Werten füllen. Dies ist die Standardeinstellung. |
AddWithKey | Die neuen Schema- und Primärschlüsselinformationen zum DataSet hinzufügen und die neuen Spalten mit den empfangenen Werten füllen. |
Error | Eine Ausnahme auslösen, wenn nicht übereinstimmende Schemainformationen gefunden werden. |
Ignore | Die neuen Schemainformationen ignorieren. |
Einschränkungen
Bei der Merge-Methode werden Einschränkungen erst überprüft, wenn alle neuen Daten zum bestehenden DataSet hinzugefügt wurden. Sobald die Daten hinzugefügt wurden, werden die Einschränkungen für die aktuellen Werte im DataSet erzwungen. Sie müssen sicherstellen, dass in Ihrem Code die Behandlung von Ausnahmen möglich ist, die aufgrund von Einschränkungsverletzungen ausgelöst werden.
Angenommen, eine bestehende Zeile in einem DataSet ist eine Unchanged-Zeile mit dem Primärschlüsselwert 1. Während einer Zusammenführung mit einer empfangenen Modified-Zeile mit dem Original-Primärschlüsselwert 2 und dem Current-Primärschlüsselwert 1 werden die bestehende und die empfangene Zeile als nicht identisch betrachtet, weil die Original-Primärschlüsselwerte verschieden sind. 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 Unique-Einschränkung für die Spalte des Primärschlüssels verletzen.
Im folgenden Codebeispiel werden zwei DataSet-Objekte mit verschiedenen Schemas in einem DataSet mit den kombinierten Schemas der beiden empfangenen DataSet-Objekte zusammengeführt.
Dim nwindConn As SqlConnection = New SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")
Dim custDA As SqlDataAdapter = New SqlDataAdapter("SELECT CustomerID, CompanyName FROM Customers", nwindConn)
nwindConn.Open()
Dim custDS As DataSet = New DataSet()
custDA.FillSchema(custDS, SchemaType.Source, "Customers")
custDA.Fill(custDS, "Customers")
Dim orderDS As DataSet = New DataSet()
orderDS.ReadXml("Orders.xml", XmlReadMode.ReadSchema)
orderDS.AcceptChanges()
nwindConn.Close()
custDS.Merge(orderDS, True, MissingSchemaAction.AddWithKey)
[C#]
SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");
SqlDataAdapter custDA = new SqlDataAdapter("SELECT CustomerID, CompanyName FROM Customers", nwindConn);
nwindConn.Open();
DataSet custDS = new DataSet();
custDA.FillSchema(custDS, SchemaType.Source, "Customers");
custDA.Fill(custDS, "Customers");
DataSet orderDS = new DataSet();
orderDS.ReadXml("Orders.xml", XmlReadMode.ReadSchema);
orderDS.AcceptChanges();
nwindConn.Close();
custDS.Merge(orderDS, true, MissingSchemaAction.AddWithKey);
Das folgende Codebeispiel nimmt ein bestehendes DataSet mit Aktualisierungen und übergibt die Aktualisierungen an einen DataAdapter, der an der Datenquelle verarbeitet werden soll. Die Ergebnisse werden anschließend im ursprünglichen DataSet zusammengeführt. 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.
Dim custTable As DataTable = custDS.Tables("Customers")
' Make modifications to the Customers table.
' Get changes to the DataSet.
Dim updDS As DataSet = custDS.GetChanges()
' Add an event handler to handle the errors during Update.
AddHandler custDA.RowUpdated, New SqlRowUpdatedEventHandler(AddressOf OnRowUpdated)
nwindConn.Open()
custDA.Update(updDS, "Customers")
nwindConn.Close()
' Merge the updates.
custDS.Merge(updDS, true, MissingSchemaAction.Add)
' Reject changes on rows with errors and clear the error.
Dim errRows() As DataRow = custDS.Tables("Customers").GetErrors()
Dim errRow As DataRow
For Each errRow In errRows
errRow.RejectChanges()
errRow.RowError = Nothing
Next
' Commit the changes.
custDS.AcceptChanges()
Private Shared Sub OnRowUpdated(sender As Object, args As SqlRowUpdatedEventArgs)
If args.Status = UpdateStatus.ErrorsOccurred
args.Row.RowError = args.Errors.Message
args.Status = UpdateStatus.SkipCurrentRow
End If
End Sub
[C#]
DataTable custTable = custDS.Tables["Customers"];
// Make modifications to the Customers table.
// Get changes to the DataSet.
DataSet updDS = custDS.GetChanges();
// Add an event handler to handle the errors during Update.
custDA.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
nwindConn.Open();
custDA.Update(updDS, "Customers");
nwindConn.Close();
// Merge the updates.
custDS.Merge(updDS, true, MissingSchemaAction.Add);
// Reject changes on rows with errors and clear the error.
DataRow[] errRows = custDS.Tables["Customers"].GetErrors();
foreach (DataRow errRow in errRows)
{
errRow.RejectChanges();
errRow.RowError = null;
}
// Commit the changes.
custDS.AcceptChanges();
protected static void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
{
if (args.Status == UpdateStatus.ErrorsOccurred)
{
args.Row.RowError = args.Errors.Message;
args.Status = UpdateStatus.SkipCurrentRow;
}
}
Siehe auch
Erstellen und Verwenden von DataSets | MissingSchemaAction-Enumeration | Zeilenstatus und Zeilenversion