Scalanie zawartości elementu DataSet
Za pomocą Merge metody można scalić zawartość tablicy DataSet, DataTablelub DataRow z istniejącą DataSet
tablicą . Kilka czynników i opcji wpływa na sposób scalania nowych danych z istniejącym DataSet
elementem .
Klucze podstawowe
Jeśli tabela odbierającą nowe dane i schemat z scalania ma klucz podstawowy, nowe wiersze z danych przychodzących są zgodne z istniejącymi wierszami, które mają te same Original wartości klucza podstawowego co te w danych przychodzących. Jeśli kolumny ze schematu przychodzącego są zgodne z tymi z istniejącego schematu, dane w istniejących wierszach zostaną zmodyfikowane. Kolumny, które nie pasują do istniejącego schematu, są ignorowane lub dodawane na podstawie parametru MissingSchemaAction . Nowe wiersze z wartościami klucza podstawowego, które nie pasują do żadnych istniejących wierszy, są dołączane do istniejącej tabeli.
Jeśli przychodzące lub istniejące wiersze mają stan Addedwiersza , ich wartości klucza podstawowego są dopasowywane przy użyciu Current wartości klucza podstawowego Added
wiersza, ponieważ nie Original
istnieje żadna wersja wiersza.
Jeśli tabela przychodząca i istniejąca tabela zawierają kolumnę o tej samej nazwie, ale różne typy danych, zgłaszany jest wyjątek i MergeFailed zgłaszane jest zdarzenie DataSet
. Jeśli zarówno tabela przychodząca, jak i istniejąca tabela mają zdefiniowane klucze, ale klucze podstawowe są przeznaczone dla różnych kolumn, zgłaszany jest wyjątek i MergeFailed
zgłaszane jest zdarzenie DataSet
.
Jeśli tabela odbieraca nowe dane ze scalania nie ma klucza podstawowego, nowe wiersze z danych przychodzących nie mogą być dopasowane do istniejących wierszy w tabeli i są zamiast tego dołączane do istniejącej tabeli.
Nazwy tabel i przestrzenie nazw
DataTable obiekty można opcjonalnie przypisać Namespace wartość właściwości. Po Namespace przypisaniu DataSet wartości może zawierać wiele DataTable obiektów o tej samej TableName wartości. Podczas operacji scalania są używane zarówno TableName Namespace do identyfikowania celu scalania. Jeśli nie Namespace zostało przypisane, tylko TableName element jest używany do identyfikowania celu scalania.
Uwaga
To zachowanie zmieniło się w wersji 2.0 programu .NET Framework. W wersji 1.1 przestrzenie nazw były obsługiwane, ale były ignorowane podczas operacji scalania. Z tego powodu DataSet użycie Namespace wartości właściwości będzie miało różne zachowania w zależności od używanej wersji programu .NET Framework. Załóżmy na przykład, że masz dwa DataSets
zawierające DataTables
te same TableName wartości właściwości, ale różne Namespace wartości właściwości. W wersji 1.1 programu .NET Framework różne Namespace nazwy będą ignorowane podczas scalania dwóch DataSet obiektów. Jednak począwszy od wersji 2.0 scalanie powoduje utworzenie dwóch nowych w DataTables
obiekcie docelowym DataSet. Oryginalny element DataTables
nie będzie mieć wpływu na scalanie.
Preservechanges
Po przekazaniu DataSet
metody , DataTable
lub DataRow
tablicy do Merge
metody można uwzględnić opcjonalne parametry określające, czy zachować zmiany w istniejącym DataSet
obiekcie oraz jak obsługiwać nowe elementy schematu znalezione w danych przychodzących. Pierwszy z tych parametrów po danych przychodzących jest flagą logiczną , która określa, PreserveChangesczy zachować zmiany w istniejącym DataSet
obiekcie . Jeśli flaga PreserveChanges
jest ustawiona na true
, wartości przychodzące nie zastępują istniejących wartości w Current
wersji wiersza istniejącego wiersza. Jeśli flaga jest ustawiona PreserveChanges
na false
, wartości przychodzące zastępują istniejące wartości w Current
wersji wiersza istniejącego wiersza. Jeśli flaga nie jest określona PreserveChanges
, jest ustawiona na false
wartość domyślną. Aby uzyskać więcej informacji na temat wersji wierszy, zobacz Row States and Row Versions (Stany wierszy i wersje wierszy).
Gdy PreserveChanges
wartość to true
, dane z istniejącego wiersza są przechowywane w Current wersji wiersza istniejącego wiersza, podczas gdy dane z Original wersji wiersza istniejącego wiersza są zastępowane danymi z Original
wersji wiersza przychodzącego wiersza. Dla RowState istniejącego wiersza ustawiono wartość Modified. Stosuje się następujące wyjątki:
Jeśli istniejący wiersz ma
RowState
wartośćDeleted
, pozostajeDeleted
onRowState
ustawiony naModified
wartość . W takim przypadku dane z wiersza przychodzącego będą nadal przechowywane wOriginal
wersji wiersza istniejącego wiersza, zastępującOriginal
wersję wiersza istniejącego wiersza (chyba że wiersz przychodzący maRowState
wartośćAdded
).Jeśli wiersz przychodzący ma
RowState
wartośćAdded
, dane zOriginal
wersji wiersza istniejącego wiersza nie zostaną zastąpione danymi z wiersza przychodzącego, ponieważ wiersz przychodzący nie maOriginal
wersji wiersza.
Gdy PreserveChanges
wartość to false
, wersje Current
wierszy i Original
w istniejącym wierszu są zastępowane danymi z wiersza przychodzącego, a istniejący RowState
wiersz jest ustawiony na RowState
wiersz przychodzący. Stosuje się następujące wyjątki:
Jeśli wiersz przychodzący ma wartość ,
RowState
Unchanged
a istniejący wiersz maRowState
Modified
wartość ,Deleted
lubAdded
,RowState
dla istniejącego wiersza ustawiono wartośćModified
.Jeśli wiersz przychodzący ma
RowState
wartość , a istniejący wiersz maUnchanged
RowState
wartość ,Modified
lubDeleted
,RowState
dla istniejącego wiersza ustawiono wartośćModified
Added
. Ponadto dane zOriginal
wersji wiersza istniejącego wiersza nie są zastępowane danymi z wiersza przychodzącego, ponieważ wiersz przychodzący nie maOriginal
wersji wiersza.
Missingschemaaction
Możesz użyć opcjonalnego MissingSchemaAction parametru Merge
metody, aby określić sposób Merge
obsługi elementów schematu w danych przychodzących, które nie są częścią istniejącego DataSet
elementu .
W poniższej tabeli opisano opcje programu MissingSchemaAction
.
MissingSchemaAction, opcja | opis |
---|---|
Add | Dodaj nowe informacje o schemacie do DataSet elementu i wypełnij nowe kolumny wartościami przychodzącymi. Jest to opcja domyślna. |
AddWithKey | Dodaj nowy schemat i informacje o kluczu DataSet podstawowym do elementu i wypełnij nowe kolumny wartościami przychodzącymi. |
Error | Zgłaszanie wyjątku w przypadku napotkania niezgodnych informacji o schemacie. |
Ignore | Ignoruj nowe informacje o schemacie. |
Ograniczenia
W przypadku Merge
metody ograniczenia nie są sprawdzane, dopóki wszystkie nowe dane nie zostaną dodane do istniejącego DataSet
elementu . Po dodaniu danych ograniczenia są wymuszane dla bieżących wartości w pliku DataSet
. Należy się upewnić, że kod obsługuje wszelkie wyjątki, które mogą zostać zgłoszone z powodu naruszeń ograniczeń.
Rozważmy przypadek, w którym istniejący wiersz w obiekcie DataSet
to Unchanged
wiersz z wartością klucza podstawowego 1. Podczas operacji scalania z wierszem przychodzącym Modified
z wartością Original
klucza podstawowego 2 i wartością Current
klucza podstawowego 1 istniejący wiersz i wiersz przychodzący nie są uznawane za zgodne, ponieważ Original
wartości klucza podstawowego różnią się. Jednak po zakończeniu scalania i sprawdzeniu ograniczeń zostanie zgłoszony wyjątek, ponieważ Current
wartości klucza podstawowego naruszają unikatowe ograniczenie dla kolumny klucza podstawowego.
Uwaga
Gdy wiersze są wstawiane do tabeli bazy danych zawierającej kolumnę automatycznego zwiększania, taką jak kolumna tożsamości, wartość kolumny tożsamości zwrócona przez wstawianie może nie odpowiadać wartości w DataSet
tabeli , co powoduje dołączenie zwracanych wierszy zamiast scalania. Aby uzyskać więcej informacji, zobacz Pobieranie tożsamości lub wartości autonumerowania.
Poniższy przykład kodu scala dwa DataSet
obiekty z różnymi schematami w jeden DataSet
ze połączonymi schematami dwóch obiektów przychodzących DataSet
.
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
Poniższy przykład kodu przyjmuje istniejący DataSet
element z aktualizacjami i przekazuje te aktualizacje do DataAdapter
przetworzenia w źródle danych. Wyniki zostaną następnie scalone z oryginalnym DataSet
elementem . Po odrzuceniu zmian, które spowodowały błąd, scalone zmiany są zatwierdzane za pomocą polecenia 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