Mesclando conteúdo do conjunto de dados
Você pode usar o Merge método para mesclar o conteúdo de um DataSet, DataTableou DataRow matriz em um arquivo DataSet
. Vários fatores e opções afetam a forma como os novos dados são mesclados em um DataSet
arquivo .
Chaves primárias
Se a tabela que recebe novos dados e esquema de uma mesclagem tiver uma chave primária, novas linhas dos dados de entrada serão correspondidas com linhas existentes que têm os mesmos Original valores de chave primária que aqueles nos dados de entrada. Se as colunas do esquema de entrada corresponderem às do esquema existente, os dados nas linhas existentes serão modificados. As colunas que não correspondem ao esquema existente são ignoradas ou adicionadas com base no MissingSchemaAction parâmetro. Novas linhas com valores de chave primária que não correspondem a nenhuma linha existente são acrescentadas à tabela existente.
Se as linhas de entrada ou existentes tiverem um estado de linha de , seus valores de Addedchave primária serão correspondidos usando o Added
Current valor de chave primária da linha porque não Original
existe nenhuma versão de linha.
Se uma tabela de entrada e uma tabela existente contiverem uma coluna com o mesmo nome, mas tipos de dados diferentes, uma exceção será lançada e o MergeFailed evento da DataSet
será gerado. Se uma tabela de entrada e uma tabela existente tiverem chaves definidas, mas as chaves primárias forem para colunas diferentes, uma exceção será lançada e o MergeFailed
evento da DataSet
será gerado.
Se a tabela que recebe novos dados de uma mesclagem não tiver uma chave primária, as novas linhas dos dados de entrada não poderão ser correspondidas às linhas existentes na tabela e, em vez disso, serão acrescentadas à tabela existente.
Nomes de tabelas e namespaces
DataTable Opcionalmente, os objetos podem receber um valor de Namespace propriedade. Quando Namespace os valores são atribuídos, um DataSet pode conter vários DataTable objetos com o mesmo TableName valor. Durante as operações de mesclagem, ambos TableName e Namespace são usados para identificar o destino de uma mesclagem. Se não Namespace tiver sido atribuído, apenas o TableName será usado para identificar o destino de uma mesclagem.
Nota
Esse comportamento foi alterado na versão 2.0 do .NET Framework. Na versão 1.1, namespaces eram suportados, mas eram ignorados durante as operações de mesclagem. Por esse motivo, um DataSet que usa Namespace valores de propriedade terá comportamentos diferentes, dependendo de qual versão do .NET Framework você está executando. Por exemplo, suponha que você tenha dois DataSets
contendo DataTables
com os mesmos TableName valores de propriedade, mas valores de propriedade diferentes Namespace . Na versão 1.1 do .NET Framework, os nomes diferentes Namespace serão ignorados ao mesclar os dois DataSet objetos. No entanto, a partir da versão 2.0, a fusão faz com que dois novos DataTables
sejam criados no destino DataSet. O original DataTables
não será afetado pela fusão.
PreserveAlterações
Ao passar um DataSet
, , ou DataRow
matriz para o Merge
método, você pode incluir parâmetros opcionais que especificam se as alterações devem ou não ser preservadas no existente DataSet
e como lidar com novos elementos de esquema encontrados nos DataTable
dados de entrada. O primeiro desses parâmetros após os dados de entrada é um sinalizador booleano, PreserveChangesque especifica se as alterações no .DataSet
Se o PreserveChanges
sinalizador estiver definido como true
, os valores de entrada não substituirão os Current
valores existentes na versão de linha da linha existente. Se o PreserveChanges
sinalizador estiver definido como false
, os valores de entrada substituem os valores existentes na Current
versão de linha da linha existente. Se o PreserveChanges
sinalizador não for especificado, ele será definido como false
por padrão. Para obter mais informações sobre versões de linha, consulte Estados de linha e versões de linha.
Quando PreserveChanges
é true
, os dados da linha existente são mantidos na Current versão da linha existente, enquanto os dados da Original versão da linha existente são substituídos pelos dados da Original
versão da linha de entrada. O RowState da linha existente é definido como Modified. Aplicam-se as seguintes exceções:
Se a linha existente tiver um
RowState
deDeleted
, issoRowState
permaneceráDeleted
e não estará definido comoModified
. Nesse caso, os dados da linha de entrada ainda serão armazenados naOriginal
versão de linha da linha existente, substituindo aOriginal
versão de linha da linha existente (a menos que a linha de entrada tenha umRowState
deAdded
).Se a linha de entrada tiver um
RowState
de , os dados daOriginal
versão de linha da linha existente não serão substituídos por dados da linha de entrada, porque a linha de entrada não tem umaOriginal
versão deAdded
linha.
Quando PreserveChanges
é false
, as versões e Original
linha Current
na linha existente são substituídas pelos dados da linha de entrada e a RowState
da linha existente é definida como a RowState
da linha de entrada. Aplicam-se as seguintes exceções:
Se a linha de entrada tiver um
RowState
de e a linha existente tiver umRowState
deModified
,Deleted
ouAdded
, aRowState
da linha existente será definida comoModified
Unchanged
.Se a linha de entrada tiver um
RowState
de , e a linha existente tiver umRowState
deUnchanged
,Modified
ouDeleted
, aRowState
da linha existente será definida comoModified
Added
. Além disso, osOriginal
dados da versão de linha da linha existente não são substituídos por dados da linha de entrada, porque a linha de entrada não tem umaOriginal
versão de linha.
MissingSchemaAction
Você pode usar o parâmetro opcional MissingSchemaAction do método para especificar como Merge
manipulará os elementos do Merge
esquema nos dados de entrada que não fazem parte do DataSet
arquivo .
A tabela a seguir descreve as opções para MissingSchemaAction
.
Opção MissingSchemaAction | Description |
---|---|
Add | Adicione as novas informações de esquema ao DataSet e preencha as novas colunas com os valores de entrada. Esta é a predefinição. |
AddWithKey | Adicione o novo esquema e as informações da chave primária ao DataSet e preencha as novas colunas com os valores de entrada. |
Error | Lance uma exceção se informações de esquema incompatíveis forem encontradas. |
Ignore | Ignore as informações do novo esquema. |
Restrições
Com o método, as restrições não são verificadas Merge
até que todos os novos dados tenham sido adicionados ao DataSet
. Depois que os dados forem adicionados, as restrições serão impostas aos valores atuais no DataSet
. Você deve garantir que seu código lide com quaisquer exceções que possam ser lançadas devido a violações de restrição.
Considere um caso em que uma linha existente em um DataSet
é uma Unchanged
linha com um valor de chave primária de 1. Durante uma operação de mesclagem com uma Modified
linha de entrada com um Original
valor de chave primária de 2 e um Current
valor de chave primária de 1, a linha existente e a linha de entrada não são consideradas correspondentes porque os valores de Original
chave primária diferem. No entanto, quando a mesclagem for concluída e as restrições forem verificadas, uma exceção será lançada porque os valores de Current
chave primária violam a restrição exclusiva para a coluna de chave primária.
Nota
Quando as linhas são inseridas em uma tabela de banco de dados que contém uma coluna de incremento automático, como uma coluna de identidade, o valor da coluna de identidade retornado pela inserção pode não corresponder ao valor no DataSet
, fazendo com que as linhas retornadas sejam acrescentadas em vez de mescladas. Para obter mais informações, consulte Recuperando valores de identidade ou de numeração automática.
O exemplo de código a seguir mescla dois DataSet
objetos com esquemas diferentes em um DataSet
com os esquemas combinados dos dois objetos de entrada 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
O exemplo de código a seguir pega um existente DataSet
com atualizações e passa essas atualizações para um DataAdapter
a ser processado na fonte de dados. Os resultados são então mesclados no original DataSet
. Depois de rejeitar as alterações que resultaram em um erro, as alterações mescladas são confirmadas com AcceptChanges
o .
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