Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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 scalanie nowych danych z istniejącym DataSet
.
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 Added wiersza, ich wartości kluczowe są dopasowywane za pomocą Current wartości klucza podstawowego Added
wiersza, ze względu na brak Original
wersji wiersza.
Jeśli tabela przychodząca i istniejąca tabela zawierają kolumnę o tej samej nazwie, ale różnych typach danych, zgłaszany jest wyjątek, a zdarzenie MergeFailed jest uruchamiane z DataSet
. Jeśli zarówno tabela przychodząca, jak i istniejąca tabela mają zdefiniowane klucze, ale klucze podstawowe dotyczą różnych kolumn, zgłaszany jest wyjątek, a zdarzenie MergeFailed
jest podnoszone dla 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
Obiekty DataTable mogą mieć opcjonalnie przypisaną wartość właściwości Namespace. Po przypisaniu wartości Namespace, DataSet może zawierać wiele obiektów DataTable o tej samej wartości TableName. Podczas operacji scalania są używane zarówno TableName i Namespace do identyfikowania celu scalania. Jeśli Namespace nie zostało przypisane, tylko TableName jest używane do identyfikowania celu scalania.
Uwaga / Notatka
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, który używa wartości właściwości Namespace, będzie się zachowywać inaczej, w zależności od wersji używanego programu .NET Framework. Załóżmy na przykład, że masz dwa DataSets
zawierające DataTables
o tych samych wartościach właściwości TableName, ale o różnych wartościach właściwości Namespace. 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 DataTables
w obiekcie docelowym DataSet. Oryginalny element DataTables
nie będzie mieć wpływu na scalanie.
Zachowaj zmiany
Przy przekazaniu tablic DataSet
, DataTable
lub DataRow
do metody Merge
można uwzględnić opcjonalne parametry określające, czy zachować zmiany w istniejącym DataSet
oraz jak obsługiwać nowe elementy schematu znalezione w danych przychodzących. Pierwszy z tych parametrów, z danych przychodzących, jest flagą logiczną PreserveChanges, która określa, czy zachować zmiany w istniejącym DataSet
. 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 PreserveChanges
jest ustawiona na false
, wartości przychodzące zastępują istniejące wartości w wersji wiersza Current
. Jeśli flaga PreserveChanges
nie jest określona, jest domyślnie ustawiona na false
. Aby uzyskać więcej informacji na temat wersji wierszy, zobacz Row States and Row Versions (Stany wierszy i wersje wierszy).
Gdy PreserveChanges
jest true
, dane z istniejącego wiersza są przechowywane w Current wersji tego wiersza, podczas gdy dane z Original wersji tego wiersza są zastępowane danymi z Original
wersji nadchodzącego wiersza. Wartość RowState istniejącego wiersza jest ustawiona na Modified. Stosuje się następujące wyjątki:
Jeśli istniejący wiersz ma wartość
RowState
wDeleted
, pozostajeRowState
i nie jest ustawiony na wartośćDeleted
. W takim przypadku dane z nadchodzącego wiersza będą nadal przechowywane wOriginal
wersji istniejącego wiersza, zastępującOriginal
wersję tego wiersza (chyba że wiersz przychodzący maRowState
Added
).Jeśli nadchodzący wiersz ma wartość
RowState
, daneAdded
wersji istniejącego wiersza nie zostaną zastąpione danymi z nadchodzącego wiersza, ponieważ nadchodzący wiersz nie ma wersji wierszaOriginal
.
Gdy PreserveChanges
jest false
, zarówno wersje wiersza Current
i Original
w istniejącym wierszu są zastępowane danymi z wiersza przychodzącego, a RowState
istniejącego wiersza jest ustawiany na RowState
wiersza przychodzącego. Stosuje się następujące wyjątki:
Jeśli wiersz przychodzący ma
RowState
o wartościUnchanged
, a istniejący wiersz maRowState
o wartościModified
,Deleted
lubAdded
, ustawRowState
istniejącego wiersza naModified
.Jeśli wiersz przychodzący ma wartość
RowState
, a istniejący wiersz ma wartośćAdded
,RowState
,Unchanged
lubModified
, wartośćDeleted
dla istniejącego wiersza jest ustawiona naRowState
. 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 parametru MissingSchemaAction metody Merge
, aby określić sposób, w jaki Merge
będzie obsługiwać elementy schematu w danych przychodzących, które nie są częścią istniejącego DataSet
.
W poniższej tabeli opisano opcje programu MissingSchemaAction
.
Opcja MissingSchemaAction | Opis |
---|---|
Add | Dodaj nowe informacje o schemacie do DataSet elementu i wypełnij nowe kolumny wartościami przychodzącymi. Jest to wartość domyślna. |
AddWithKey | Dodaj nowy schemat oraz informacje o kluczu podstawowym do DataSet i wypełnij nowe kolumny wartością przychodzącymi. |
Error | Zgłoś wyjątek, gdy zidentyfikowane zostaną niezgodne informacje o schemacie. |
Ignore | Ignoruj nowe informacje o schemacie. |
Ograniczenia
Metoda Merge
powoduje, że ograniczenia nie są sprawdzane, dopóki wszystkie nowe dane nie zostaną dodane do istniejącego DataSet
. 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 tabeli DataSet
jest wierszem typu Unchanged
z wartością klucza podstawowego równą 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 / Notatka
Gdy wstawiane są wiersze do tabeli bazy danych z kolumną automatycznie zwiększaną, taką jak kolumna identyfikatorów, wartość tej kolumny zwrócona przez operację może nie odpowiadać wartości w DataSet
tabeli, co powoduje dodanie zwracanych wierszy zamiast ich scalania. Aby uzyskać więcej informacji, zobacz Pobieranie identyfikatorów lub wartości automatycznego numerowania.
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
z aktualizacjami i przekazuje te aktualizacje do DataAdapter
w celu przetworzenia w źródle danych. Wyniki są następnie łączone z oryginalnym elementem DataSet
. 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