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 DataSetparametr , DataTablenebo DataRow pole Merge , můžete zahrnout volitelné parametry, které určují, zda chcete zachovat změny v existující DataSeta 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 truetak, 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ůstane Deleted a není nastaven na Modified. V tomto případě budou data z příchozího řádku uložena ve Original 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žku Added, nebudou data z Original 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 hodnotu Modified, Deletednebo Added, RowState je existující řádek nastaven na Modifiedhodnotu .

  • Pokud má příchozí řádek hodnotu RowState Addeda existující řádek má RowState Unchangedhodnotu , Modifiednebo Deletedje RowState nastavena hodnota existujícího řádku Modified. Data z Original 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 DataSettabulce 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 DataSetsouboru . 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

Viz také