Dela via


Slå samman datauppsättningsinnehåll

Du kan använda Merge metoden för att sammanfoga innehållet i en DataSet, DataTableeller DataRow -matris till en befintlig DataSet. Flera faktorer och alternativ påverkar hur nya data sammanfogas till en befintlig DataSet.

Primärnycklar

Om den tabell som tar emot nya data och scheman från en sammanslagning har en primärnyckel matchas nya rader från inkommande data med befintliga rader som har samma Original primärnyckelvärden som de i inkommande data. Om kolumnerna från det inkommande schemat matchar det befintliga schemat ändras data i de befintliga raderna. Kolumner som inte matchar det befintliga schemat ignoreras eller läggs till baserat på parametern MissingSchemaAction . Nya rader med primärnyckelvärden som inte matchar några befintliga rader läggs till i den befintliga tabellen.

Om inkommande eller befintliga rader har radtillståndet Addedmatchas deras primära nyckelvärden med radens Current primära nyckelvärde Added eftersom det inte finns någon Original radversion.

Om en inkommande tabell och en befintlig tabell innehåller en kolumn med samma namn men olika datatyper genereras ett undantag och MergeFailed händelsen för utlöses DataSet . Om både en inkommande tabell och en befintlig tabell har definierade nycklar, men de primära nycklarna är för olika kolumner, utlöses ett undantag och MergeFailed händelsen DataSet aktiveras.

Om tabellen som tar emot nya data från en sammanslagning inte har någon primärnyckel kan nya rader från inkommande data inte matchas mot befintliga rader i tabellen och läggs i stället till i den befintliga tabellen.

Tabellnamn och namnområden

DataTable objekt kan också tilldelas ett Namespace egenskapsvärde. När Namespace värden tilldelas kan en DataSet innehålla flera DataTable objekt med samma TableName värde. Under sammanslagningsåtgärder används både TableName och Namespace för att identifiera målet för en sammanslagning. Om inget Namespace har tilldelats används endast TableName för att identifiera målet för en sammanslagning.

Kommentar

Det här beteendet ändrades i version 2.0 av .NET Framework. I version 1.1 stöddes namnområden men ignorerades under sammanslagningsåtgärder. Därför har en DataSet som använder Namespace egenskapsvärden olika beteenden beroende på vilken version av .NET Framework du kör. Anta till exempel att du har två DataSets som innehåller DataTables samma TableName egenskapsvärden men olika Namespace egenskapsvärden. I version 1.1 av .NET Framework ignoreras de olika Namespace namnen när de två DataSet objekten slås samman. Men från och med version 2.0 skapar sammanslagning två nya DataTables i målet DataSet. DataTables Originalet påverkas inte av kopplingen.

PreserveChanges

När du skickar en DataSet, DataTable, eller DataRow -matris till Merge metoden kan du inkludera valfria parametrar som anger om ändringar ska bevaras i befintliga DataSet, och hur du hanterar nya schemaelement som finns i inkommande data. Den första av dessa parametrar efter inkommande data är en boolesk flagga, , PreserveChangessom anger om ändringarna i den befintliga DataSet. PreserveChanges Om flaggan är inställd på trueskriver inkommande värden inte över befintliga värden i Current radversionen av den befintliga raden. PreserveChanges Om flaggan är inställd på falseskriver inkommande värden över de befintliga värdena i Current radversionen av den befintliga raden. PreserveChanges Om flaggan inte har angetts är den inställd false på som standard. Mer information om radversioner finns i Radtillstånd och Radversioner.

När PreserveChanges är trueunderhålls data från den befintliga raden i Current radversionen av den befintliga raden, medan data från Original radversionen av den befintliga raden skrivs över med data från Original radversionen av den inkommande raden. Den RowState befintliga raden är inställd på Modified. Följande undantag gäller:

  • Om den befintliga raden har en RowState av Deletedförblir Deleted detta RowState och är inte inställt på Modified. I det här fallet lagras data från den inkommande raden fortfarande i Original radversionen av den befintliga raden och skriver Original över radversionen av den befintliga raden (såvida inte den inkommande raden har värdet RowState Added).

  • Om den inkommande raden har en RowState av Addedskrivs inte data från Original radversionen av den befintliga raden över med data från den inkommande raden, eftersom den inkommande raden inte har någon Original radversion.

När PreserveChanges är falseskrivs både radversionerna Current och Original i den befintliga raden över med data från den inkommande raden, och den RowState befintliga raden anges till den RowState inkommande radens. Följande undantag gäller:

  • Om den inkommande raden har en RowState av Unchanged och den befintliga raden har värdet RowState Modified, Deleted, eller Added, är den RowState befintliga raden inställd på Modified.

  • Om den inkommande raden har en RowState av Added, och den befintliga raden har värdet RowState Unchanged, Modified, eller Deleted, är den RowState befintliga raden inställd på Modified. Dessutom skrivs inte data från Original radversionen av den befintliga raden över med data från den inkommande raden, eftersom den inkommande raden inte har någon Original radversion.

MissingSchemaAction

Du kan använda den valfria MissingSchemaAction parametern för Merge metoden för att ange hur Merge schemaelement ska hanteras i inkommande data som inte ingår i den befintliga DataSet.

I följande tabell beskrivs alternativen för MissingSchemaAction.

MissingSchemaAction-alternativ beskrivning
Add Lägg till den nya schemainformationen i DataSet och fyll i de nya kolumnerna med inkommande värden. Det här är standardinställningen.
AddWithKey Lägg till det nya schemat och primärnyckelinformationen i DataSet och fyll i de nya kolumnerna med inkommande värden.
Error Utlös ett undantag om felmatchad schemainformation påträffas.
Ignore Ignorera den nya schemainformationen.

Krav

Merge Med metoden kontrolleras inte begränsningar förrän alla nya data har lagts till i den befintliga DataSet. När data har lagts till tillämpas begränsningar på de aktuella värdena i DataSet. Du måste se till att koden hanterar eventuella undantag som kan uppstå på grund av begränsningsöverträdelser.

Tänk dig ett fall där en befintlig rad i en DataSet är en Unchanged rad med primärnyckelvärdet 1. Under en sammanslagningsåtgärd med en Modified inkommande rad med ett Original primärnyckelvärde på 2 och ett Current primärnyckelvärde på 1 anses den befintliga raden och den inkommande raden inte matcha eftersom de Original primära nyckelvärdena skiljer sig åt. Men när sammanfogningen har slutförts och begränsningarna har markerats utlöses ett undantag eftersom primärnyckelvärdena Current bryter mot den unika begränsningen för primärnyckelkolumnen.

Kommentar

När rader infogas i en databastabell som innehåller en automatisk inkrementell kolumn, till exempel en identitetskolumn, kanske värdet för identitetskolumnen som returneras av infogningen inte matchar värdet i DataSet, vilket gör att de returnerade raderna läggs till i stället för sammanfogade. Mer information finns i Hämta identitets- eller räknarevärden.

I följande kodexempel sammanfogas två DataSet objekt med olika scheman till ett DataSet med de kombinerade schemana för de två inkommande DataSet objekten.

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

Följande kodexempel tar en befintlig DataSet med uppdateringar och skickar dessa uppdateringar till en DataAdapter som ska bearbetas i datakällan. Resultatet sammanfogas sedan till den ursprungliga DataSet. När du har avvisat ändringar som resulterade i ett fel checkas de sammanslagna ändringarna in med 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

Se även