Adathalmaz tartalmának egyesítése
A metódussal Merge egyesítheti egy DataSet, DataTablevagy DataRow tömb tartalmát egy meglévőbe DataSet
. Az új adatok meglévővé DataSet
való egyesítése több tényezőt és lehetőséget is érint.
Elsődleges kulcsok
Ha az egyesítésből új adatokat és sémát fogadó tábla elsődleges kulccsal rendelkezik, a bejövő adatok új sorai megegyeznek azokkal a meglévő sorokkal, amelyek elsődleges kulcsértéke megegyezik Original a bejövő adatokban szereplő értékekkel. Ha a bejövő séma oszlopai megegyeznek a meglévő sémáéval, a meglévő sorokban lévő adatok módosulnak. A meglévő sémával nem egyező oszlopok a paraméter alapján MissingSchemaAction figyelmen kívül hagyhatók vagy hozzáadhatók. A meglévő táblához olyan új sorok lesznek hozzáfűzve, amelyek elsődleges kulcsértékeivel nem egyeznek meg.
Ha a bejövő vagy meglévő sorok sorállapotúak Added, akkor az elsődleges kulcsértékek a Current sor elsődleges kulcsértékével Added
vannak egyeztetve, mert nem Original
létezik sorverzió.
Ha egy bejövő tábla és egy meglévő tábla azonos nevű, de eltérő adattípusú oszlopot tartalmaz, a rendszer kivételt hoz létre, és az MergeFailedDataSet
esemény bekövetkezik. Ha egy bejövő és egy meglévő tábla is rendelkezik definiált kulcsokkal, de az elsődleges kulcsok különböző oszlopokhoz tartoznak, a rendszer kivételt vet ki, és az MergeFailed
DataSet
esemény bekövetkezik.
Ha az egyesítésből új adatokat fogadó tábla nem rendelkezik elsődleges kulccsal, a bejövő adatok új sorai nem egyeznek a tábla meglévő soraival, és ehelyett hozzá vannak fűzve a meglévő táblához.
Táblanevek és névterek
DataTable az objektumok opcionálisan tulajdonságértéket Namespace is hozzárendelhetnek. Értékek hozzárendelése esetén Namespace a rendszer több DataTable azonos értékű objektumot TableName is DataSet tartalmazhat. Az egyesítési műveletek során mindkettő TableName , és Namespace az egyesítés céljának azonosítására szolgál. Ha nincs Namespace hozzárendelve, csak az TableName egyesítés céljának azonosítására szolgál.
Feljegyzés
Ez a viselkedés megváltozott a .NET-keretrendszer 2.0-s verziójában. Az 1.1-es verzióban a névterek támogatottak voltak, de az egyesítési műveletek során figyelmen kívül hagyták őket. Ezért a tulajdonságértékeket használó Namespace függvények viselkedése eltérő lesz attól függően, DataSet hogy melyik verziójú .NET-keretrendszer fut. Tegyük fel például, hogy kettő DataSets
ugyanazokkal TableName a tulajdonságértékekkel, de eltérő Namespace tulajdonságértékekkel rendelkezikDataTables
. A .NET-keretrendszer 1.1-es verziójában a rendszer figyelmen kívül hagyja a különböző Namespace neveket a két DataSet objektum egyesítésekor. A 2.0-s verziótól kezdve azonban az egyesítés két újat DataTables
hoz létre a célban DataSet. Az eredetit DataTables
az egyesítés nem érinti.
PreserveChanges
Amikor egy , DataTable
vagy DataRow
tömböt ad át DataSet
a Merge
metódusnak, olyan választható paramétereket is megadhat, amelyek megadják, hogy meg szeretné-e őrizni a meglévő DataSet
módosításokat, és hogyan kezelheti a bejövő adatokban található új sémaelemeket. A bejövő adatok utáni paraméterek közül az első egy logikai jelölő, amely meghatározza, PreserveChangeshogy a meglévőben DataSet
lévő módosítások megmaradnak-e. Ha a PreserveChanges
jelölő értéke be van állítva true
, a bejövő értékek nem felülírják a Current
meglévő sor sorverziójának meglévő értékeit. Ha a PreserveChanges
jelölő értéke a következő, false
a bejövő értékek felülírják a Current
meglévő sor sorverziójának meglévő értékeit. Ha a PreserveChanges
jelölő nincs megadva, alapértelmezés szerint be van állítva false
. További információ a sorverziókról: Sorállapotok és sorverziók.
Ha PreserveChanges
igen true
, akkor a meglévő sor adatai a meglévő sor sorverziójában Current maradnak fenn, míg a meglévő sor sorverziójának adatai Original felülíródnak a bejövő sor sorverziójának adataival Original
. A RowState meglévő sor értéke Modified. A következő kivételek érvényesek:
Ha a meglévő sornak van egy
RowState
értékeDeleted
, azRowState
megmaradDeleted
, és nincs beállítvaModified
. Ebben az esetben a bejövő sor adatai továbbra is aOriginal
meglévő sor sorverziójában lesznek tárolva, felülírva aOriginal
meglévő sor sorverzióját (kivéve, ha a bejövő sorhoz tartozikRowState
Added
egy).Ha a bejövő sorból van egy
Added
RowState
, akkor a meglévő sor sorverziójának adataiOriginal
nem lesznek felülírva a bejövő sorból származó adatokkal, mert a bejövő sor nem rendelkezikOriginal
sorverzióval.
Ha PreserveChanges
igen false
, a Current
meglévő sor és Original
a sor verziói is felülíródnak a bejövő sor adataival, a RowState
meglévő sor pedig a bejövő sorra van állítva RowState
. A következő kivételek érvényesek:
Ha a bejövő sornak van egy
RowState
részeUnchanged
, és a meglévő sorRowState
Modified
egy ,Deleted
vagyAdded
, akkor aRowState
meglévő sorModified
értéke a következő.Ha a bejövő sornak van egy
RowState
részeAdded
, és a meglévő sorból van egyUnchanged
RowState
,Modified
vagyDeleted
aRowState
meglévő sorModified
értéke. A meglévő sor sorverziójának adataitOriginal
a rendszer nem írja felül a bejövő sorból származó adatokkal, mert a bejövő sor nem rendelkezikOriginal
sorverzióval.
MissingSchemaAction
A metódus opcionális MissingSchemaAction paraméterével Merge
megadhatja, hogyan Merge
kezeli a bejövő adatok azon sémaelemét, amely nem része a meglévőnek DataSet
.
Az alábbi táblázat a beállítási lehetőségeket MissingSchemaAction
ismerteti.
MissingSchemaAction beállítás | Leírás |
---|---|
Add | Adja hozzá az új sémaadatokat, DataSet és töltse fel az új oszlopokat a bejövő értékekkel. Ez az alapértelmezett beállítás. |
AddWithKey | Adja hozzá az új sémát és az elsődleges kulcs adatait az DataSet új oszlopokhoz, és töltse fel az új oszlopokat a bejövő értékekkel. |
Error | Kivételt eredményez, ha nem egyező sémainformációk jelennek meg. |
Ignore | Hagyja figyelmen kívül az új sémainformációkat. |
Megszorítások
A metódussal a Merge
kényszerek nem lesznek bejelölve, amíg az összes új adat hozzá nem lett adva a meglévőhez DataSet
. Az adatok hozzáadása után a rendszer kényszeríti a korlátozásokat a DataSet
. Gondoskodnia kell arról, hogy a kód kezelje a korlátozás megsértése miatt esetlegesen felmerülő kivételeket.
Fontolja meg azt az esetet, amikor egy DataSet
meglévő sor egy Unchanged
olyan sor, amelynek elsődleges kulcsértéke 1. A 2 elsődleges kulcsértékkel és Current
1 elsődleges kulcsértékkel rendelkező Modified
Original
bejövő sor egyesítési művelete során a meglévő és a bejövő sor nem tekinthető egyezőnek, mert az Original
elsődleges kulcs értékei eltérnek. Ha azonban az egyesítés befejeződött, és a kényszerek ellenőrzése megtörtént, a rendszer kivételt küld, mert az Current
elsődleges kulcs értékei megsértik az elsődleges kulcs oszlopának egyedi korlátozását.
Feljegyzés
Ha sorokat szúr be egy automatikusan növekvő oszlopot (például identitásoszlopot) tartalmazó adatbázistáblába, előfordulhat, hogy a beszúrás által visszaadott identitásoszlop értéke nem egyezik meg a DataSet
beszúrt értékkel, így a visszaadott sorok összevonás helyett hozzáfűzhetők. További információ: Identitás vagy számértékek lekérése.
Az alábbi példakód két DataSet
különböző sémával rendelkező objektumot egyesít egybe DataSet
a két bejövő DataSet
objektum egyesített sémáival.
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
Az alábbi példakód egy meglévőt DataSet
használ a frissítésekkel, és átadja ezeket a frissítéseket egy DataAdapter
feldolgozandó adatforrásnak. Az eredmények ezután egyesülnek az eredeti DataSet
. A hibát eredményező módosítások elvetése után az egyesített módosítások véglegesítve lesznek a következővel AcceptChanges
: .
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