Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Você pode usar o método Merge para mesclar o conteúdo de uma matriz DataSet, DataTable ou DataRow num DataSet existente. Vários fatores e opções afetam a forma como os novos dados são mesclados em um DataSetarquivo .
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 Added, os seus valores de chave primária são correspondidos usando o valor de chave primária Current da linha Added porque não existe nenhuma versão de linha Original.
Se uma tabela de entrada e uma tabela existente contiverem uma coluna com o mesmo nome, mas com tipos de dados diferentes, será lançada uma exceção e o evento MergeFailed de 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 é lançada e o evento MergeFailed do DataSet é 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.
Observação
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 tenha dois DataSets contendo DataTables com os mesmos valores de propriedade TableName, mas com diferentes valores de propriedade 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.
Preservar Alterações
Ao passar uma matriz DataSet, DataTable ou DataRow para o método Merge, pode-se incluir parâmetros opcionais que especificam se devem ou não ser preservadas as alterações no DataSet existente e como lidar com novos elementos de esquema encontrados nos dados DataTable de entrada. O primeiro desses parâmetros após os dados de entrada é um sinalizador booleano, PreserveChanges, que especifica se as alterações existentes em DataSet devem ou não ser preservadas. 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 a flag PreserveChanges estiver definida como false, os valores de entrada substituem os valores existentes na versão de linha existente Current. 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 versão Current da linha existente são mantidos, enquanto os dados da versão Original da linha existente são substituídos pelos dados da versão Original da linha que está chegando. O RowState da linha existente é definido como Modified. Aplicam-se as seguintes exceções:
Se a linha existente tiver um
RowStatedeDeleted, esteRowStatepermaneceráDeletede não será definido comoModified. Nesse caso, os dados da linha de entrada ainda serão armazenados naOriginalversão de linha da linha existente, substituindo aOriginalversão de linha da linha existente (a menos que a linha de entrada tenha umRowStatedeAdded).Se a linha de entrada tiver um
RowStatedeAdded, os dados da versão de linhaOriginalda linha existente não serão substituídos por dados da linha de entrada, porque a linha de entrada não possui uma versão de linhaOriginal.
Quando PreserveChanges é false, as versões de linha Current e Original na linha existente são substituídas pelos dados da linha de entrada, e a RowState da linha existente é alterada para a RowState da linha de entrada. Aplicam-se as seguintes exceções:
Se a linha de entrada tiver um
RowStatedeUnchangede a linha existente tiver umRowStatedeModified,Deleted, ouAdded, aRowStateda linha existente será definida comoModified.Se a linha de entrada tiver um
RowStatedeAdded, e a linha existente tiver umRowStatedeUnchanged,ModifiedouDeleted, aRowStateda linha existente será definida comoModified. Além disso, os dados da versão de linhaOriginalda linha existente não são substituídos pelos dados da linha de entrada, porque esta não tem uma versão de linhaOriginal.
MissingSchemaAction
Você pode usar o parâmetro opcional MissingSchemaAction do método Merge para especificar como Merge manipulará os elementos de esquema nos dados de entrada que não fazem parte do DataSet existente.
A tabela a seguir descreve as opções para MissingSchemaAction.
| Opção "MissingSchemaAction" | Descrição |
|---|---|
| Add | Adicione as novas informações de esquema ao DataSet e preencha as novas colunas com os valores de entrada. Este é o padrã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 Merge, as restrições não são verificadas até que todos os novos dados tenham sido adicionados ao existente DataSet. Depois que os dados forem adicionados, as restrições serão impostas aos valores atuais no DataSet. Deve garantir que o seu código trate quaisquer exceções que possam surgir devido a violações de restrições.
Considere um cenário em que uma linha existente em um DataSet seja uma linha Unchanged 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.
Observação
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 utiliza um DataSet já existente com atualizações e passa essas atualizações para um DataAdapter a fim de serem processadas na fonte de dados. Os resultados são então integrados no original DataSet. Depois de rejeitar as alterações que resultaram em erro, as alterações fundidas são confirmadas com 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