Slučování obsahu datové sady
Pomocí metody lze Merge sloučit obsah , DataSetDataTablenebo DataRow pole do existujícího DataSet
. Několik faktorů a možností ovlivňuje, jak se nová data sloučí do existujícího DataSet
.
Primární klíče
Pokud tabulka, která přijímá nová data a schéma ze sloučení, má primární klíč, budou se nové řádky z příchozích dat shodovat s existujícími řádky, které mají stejné Original hodnoty primárního klíče jako v příchozích datech. Pokud sloupce z příchozího schématu odpovídají existujícímu schématu, data v existujících řádcích se upraví. Sloupce, které neodpovídají existujícímu schématu, se ignorují nebo přidávají na základě parametru MissingSchemaAction . Nové řádky s hodnotami primárního klíče, které neodpovídají žádným existujícím řádkům, se připojí k existující tabulce.
Pokud mají příchozí nebo existující řádky stav Addedřádku , odpovídají jejich hodnotám Current primárního klíče hodnota primárního Added
klíče řádku, protože neexistuje žádná Original
verze řádku.
Pokud příchozí tabulka a existující tabulka obsahují sloupec se stejným názvem, ale různé datové typy, vyvolá se výjimka a MergeFailed vyvolá se událost DataSet
. Pokud příchozí tabulka i existující tabulka mají definované klíče, ale primární klíče jsou pro různé sloupce, vyvolá se výjimka a MergeFailed
vyvolá se událost DataSet
.
Pokud tabulka, která přijímá nová data ze sloučení, nemá primární klíč, nové řádky z příchozích dat nelze spárovat s existujícími řádky v tabulce a jsou místo toho připojeny k existující tabulce.
Názvy tabulek a obory názvů
DataTable objekty lze volitelně přiřadit Namespace hodnotu vlastnosti. Při Namespace přiřazení DataSet hodnot může obsahovat více DataTable objektů se stejnou TableName hodnotou. Během operací TableName Namespace sloučení slouží k identifikaci cíle sloučení. Pokud není přiřazeno žádné Namespace , použije se pouze k TableName identifikaci cíle sloučení.
Poznámka:
Toto chování se změnilo ve verzi 2.0 rozhraní .NET Framework. Ve verzi 1.1 byly obory názvů podporovány, ale během operací sloučení byly ignorovány. Z tohoto důvodu budou hodnoty vlastností, které používajíNamespace, DataSet různé chování v závislosti na tom, jakou verzi rozhraní .NET Framework používáte. Předpokládejme například, že máte dva DataSets
obsahující DataTables
stejné TableName hodnoty vlastností, ale různé Namespace hodnoty vlastností. Ve verzi 1.1 rozhraní .NET Framework budou při slučování těchto dvou DataSet objektů ignorovány různé Namespace názvy. Sloučení však od verze 2.0 způsobí vytvoření dvou nových DataTables
v cíli DataSet. DataTables
Sloučením nebude ovlivněn původní.
Preservechanges
Když metodě předáte DataSet
parametr , DataTable
nebo DataRow
pole Merge
, můžete zahrnout volitelné parametry, které určují, zda chcete zachovat změny v existující DataSet
a jak zpracovat nové prvky schématu nalezené v příchozích datech. První z těchto parametrů za příchozími daty je logický příznak, který určuje, PreserveChangeszda chcete zachovat změny v existujícím DataSet
. PreserveChanges
Pokud je příznak nastaven na true
, příchozí hodnoty nepřepíšou existující hodnoty ve Current
verzi řádku existujícího řádku. PreserveChanges
Pokud je příznak nastaven na false
, příchozí hodnoty přepíšou existující hodnoty ve Current
verzi řádku existujícího řádku. PreserveChanges
Pokud není příznak zadán, nastaví se false
ve výchozím nastavení. Další informace overzích
Pokud PreserveChanges
je tomu true
tak, data z existujícího řádku jsou zachována ve Current verzi řádku existujícího řádku, zatímco data z Original verze řádku existujícího řádku se přepíšou daty z Original
verze řádku příchozího řádku. Existující RowState řádek je nastaven na Modifiedhodnotu . Platí následující výjimky:
Pokud má existující řádek hodnotu
RowState
Deleted
,RowState
zůstaneDeleted
a není nastaven naModified
. V tomto případě budou data z příchozího řádku uložena veOriginal
verzi řádku existujícího řádku a přepisujíOriginal
verzi řádku existujícího řádku (pokud příchozí řádek nemáRowState
Added
).Pokud má příchozí řádek určitou
RowState
položkuAdded
, nebudou data zOriginal
verze řádku existujícího řádku přepsána daty z příchozího řádku, protože příchozí řádek nemáOriginal
verzi řádku.
Pokud PreserveChanges
ano false
, verze Current
Original
řádků v existujícím řádku se přepíšou daty z příchozího řádku a RowState
existující řádek se nastaví na RowState
příchozí řádek. Platí následující výjimky:
Pokud má příchozí řádek hodnotu
RowState
Unchanged
a existující řádek máRowState
hodnotuModified
,Deleted
neboAdded
,RowState
je existující řádek nastaven naModified
hodnotu .Pokud má příchozí řádek hodnotu
RowState
Added
a existující řádek máRowState
Unchanged
hodnotu ,Modified
neboDeleted
jeRowState
nastavena hodnota existujícího řádkuModified
. Data zOriginal
verze řádku existujícího řádku se také nepřepíšou daty z příchozího řádku, protože příchozí řádek nemáOriginal
verzi řádku.
Missingschemaaction
Pomocí volitelného parametru Merge
metody můžete určit, jak Merge
bude zpracovávat prvky schématu v příchozích datech, které nejsou součástí existujícího DataSet
.MissingSchemaAction
Následující tabulka popisuje možnosti pro MissingSchemaAction
.
Možnost MissingSchemaAction | Popis |
---|---|
Add | Přidejte nové informace o schématu DataSet do nových sloupců a naplňte je příchozími hodnotami. Tato možnost je výchozí. |
AddWithKey | Přidejte nové schéma a informace o primárním klíči do DataSet nových sloupců a naplňte je příchozími hodnotami. |
Error | Vyvolá výjimku, pokud dojde k neshodě informací o schématu. |
Ignore | Ignorujte informace o novém schématu. |
Omezení
S metodou Merge
nejsou omezení kontrolována, dokud nebudou přidána všechna nová data do existujícího DataSet
. Po přidání dat se omezení vynucují u aktuálních hodnot v objektu DataSet
. Musíte zajistit, aby váš kód zpracovával všechny výjimky, které by mohly být vyvolány kvůli narušení omezení.
Představte si případ, kdy je Unchanged
existující řádek v DataSet
řádku s hodnotou primárního klíče 1. Během operace sloučení s příchozím Modified
řádkem s Original
hodnotou primárního klíče 2 a Current
hodnotou primárního klíče 1 se stávající řádek a příchozí řádek nepovažují za odpovídající, protože hodnoty primárního Original
klíče se liší. Při dokončení sloučení a kontrole omezení se však vyvolá výjimka, protože Current
hodnoty primárního klíče porušují jedinečné omezení sloupce primárního klíče.
Poznámka:
Pokud jsou řádky vloženy do databázové tabulky obsahující sloupec automatického zvýšení, jako je sloupec identity, hodnota sloupce identity vrácená vložením nemusí odpovídat hodnotě v DataSet
tabulce databáze, což způsobí, že vrácené řádky budou přidány místo sloučení. Další informace naleznete v tématu Načítání hodnot identity nebo automatického číslování.
Následující příklad kódu sloučí dva DataSet
objekty s různými schématy do jednoho DataSet
s kombinovanými schématy dvou příchozích DataSet
objektů.
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
Následující příklad kódu vezme existující DataSet
s aktualizacemi a předá tyto aktualizace ke DataAdapter
zpracování ve zdroji dat. Výsledky se pak sloučí do původního DataSet
souboru . Po odmítnutí změn, které způsobily chybu, se sloučené změny potvrdí s 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