Manipulando eventos DataAdapter
O ADO.NET DataAdapter expõe três eventos que você pode usar para responder a alterações feitas nos dados na fonte de dados. A tabela a seguir mostra os DataAdapter
eventos.
Evento | Descrição |
---|---|
RowUpdating |
Uma operação UPDATE, INSERT ou DELETE em uma linha (por uma chamada para um dos métodos) está prestes a Update começar. |
RowUpdated |
Uma operação UPDATE, INSERT ou DELETE em uma linha (por uma chamada para um dos Update métodos) está concluída. |
FillError |
Ocorreu um erro durante uma Fill operação. |
RowUpdating e RowUpdated
RowUpdating
é gerado antes de qualquer atualização para uma linha do DataSet tenha sido processada na fonte de dados. RowUpdated
é gerado após qualquer atualização de uma linha do DataSet
ter sido processada na fonte de dados. Como resultado, você pode usar RowUpdating
para modificar o comportamento da atualização antes que ela aconteça, para fornecer tratamento adicional quando uma atualização ocorrerá, para manter uma referência a uma linha atualizada, para cancelar a atualização atual e agendar para que um processo em lote seja processado posteriormente e assim por diante. RowUpdated
é útil para responder a erros e exceções que ocorrem durante a atualização. Você pode adicionar informações de erro ao DataSet
, bem como lógica de repetição e assim por diante.
Os RowUpdatingEventArgs argumentos e RowUpdatedEventArgs passados para os RowUpdating
eventos e RowUpdated
incluem o seguinte: uma Command
propriedade que faz referência ao Command
objeto que está sendo usado para executar a atualização, uma Row
propriedade que faz referência ao DataRow
objeto que contém as informações atualizadas, uma StatementType
propriedade para que tipo de atualização está sendo executada, o TableMapping
, se aplicável, e o Status
da operação.
Você pode usar a Status
propriedade para determinar se ocorreu um erro durante a operação e, se desejar, para controlar as ações em relação às linhas atuais e resultantes. Quando o evento ocorre, a propriedade é igual a Status
ou ErrorsOccurred
Continue
. A tabela a seguir mostra os valores para os quais você pode definir a Status
propriedade para controlar ações posteriores durante a atualização.
Status | Description |
---|---|
Continue |
Continue a operação de atualização. |
ErrorsOccurred |
Anule a operação de atualização e lance uma exceção. |
SkipCurrentRow |
Ignore a linha atual e continue a operação de atualização. |
SkipAllRemainingRows |
Anule a operação de atualização, mas não lance uma exceção. |
Definir a Status
propriedade como ErrorsOccurred
faz com que uma exceção seja lançada. Você pode controlar qual exceção é lançada definindo a Errors
propriedade como a exceção desejada. Usar um dos outros valores para Status
impede que uma exceção seja lançada.
Você também pode usar a ContinueUpdateOnError
propriedade para manipular erros para linhas atualizadas. Se DataAdapter.ContinueUpdateOnError
for true
, quando uma atualização de uma linha resulta em uma exceção sendo lançada, o texto da exceção é colocado nas informações da linha específica e o RowError
processamento continua sem lançar uma exceção. Isso permite que você responda a erros quando o Update
é concluído, em contraste com o evento, o RowUpdated
que permite que você responda a erros quando o erro é encontrado.
O exemplo de código a seguir mostra como adicionar e remover manipuladores de eventos. O RowUpdating
manipulador de eventos grava um log de todos os registros excluídos com um carimbo de data/hora. O RowUpdated
manipulador de eventos adiciona informações de erro à RowError
propriedade da linha no DataSet
, suprime a exceção e continua o processamento (espelhando o comportamento de = ContinueUpdateOnError
true
).
' Assumes that connection is a valid SqlConnection object.
Dim custAdapter As SqlDataAdapter = New SqlDataAdapter( _
"SELECT CustomerID, CompanyName FROM Customers", connection)
' Add handlers.
AddHandler custAdapter.RowUpdating, New SqlRowUpdatingEventHandler( _
AddressOf OnRowUpdating)
AddHandler custAdapter.RowUpdated, New SqlRowUpdatedEventHandler(
AddressOf OnRowUpdated)
' Set DataAdapter command properties, fill DataSet, and modify DataSet.
custAdapter.Update(custDS, "Customers")
' Remove handlers.
RemoveHandler custAdapter.RowUpdating, _
New SqlRowUpdatingEventHandler(AddressOf OnRowUpdating)
RemoveHandler custAdapter.RowUpdated, _
New SqlRowUpdatedEventHandler(AddressOf OnRowUpdated)
Private Shared Sub OnRowUpdating(sender As Object, _
args As SqlRowUpdatingEventArgs)
If args.StatementType = StatementType.Delete Then
Dim tw As System.IO.TextWriter = _
System.IO.File.AppendText("Deletes.log")
tw.WriteLine( _
"{0}: Customer {1} Deleted.", DateTime.Now, args.Row(_
"CustomerID", DataRowVersion.Original))
tw.Close()
End If
End Sub
Private Shared Sub OnRowUpdated( _
sender As Object, args As SqlRowUpdatedEventArgs)
If args.Status = UpdateStatus.ErrorsOccurred
args.Status = UpdateStatus.SkipCurrentRow
args.Row.RowError = args.Errors.Message
End If
End Sub
// Assumes that connection is a valid SqlConnection object.
SqlDataAdapter custAdapter = new SqlDataAdapter(
"SELECT CustomerID, CompanyName FROM Customers", connection);
// Add handlers.
custAdapter.RowUpdating += new SqlRowUpdatingEventHandler(OnRowUpdating);
custAdapter.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
// Set DataAdapter command properties, fill DataSet, modify DataSet.
custAdapter.Update(custDS, "Customers");
// Remove handlers.
custAdapter.RowUpdating -= new SqlRowUpdatingEventHandler(OnRowUpdating);
custAdapter.RowUpdated -= new SqlRowUpdatedEventHandler(OnRowUpdated);
protected static void OnRowUpdating(
object sender, SqlRowUpdatingEventArgs args)
{
if (args.StatementType == StatementType.Delete)
{
System.IO.TextWriter tw = System.IO.File.AppendText("Deletes.log");
tw.WriteLine(
"{0}: Customer {1} Deleted.", DateTime.Now,
args.Row["CustomerID", DataRowVersion.Original]);
tw.Close();
}
}
protected static void OnRowUpdated(
object sender, SqlRowUpdatedEventArgs args)
{
if (args.Status == UpdateStatus.ErrorsOccurred)
{
args.Row.RowError = args.Errors.Message;
args.Status = UpdateStatus.SkipCurrentRow;
}
}
FillError
O DataAdapter
emite o FillError
evento quando ocorre um erro durante uma Fill
operação. Esse tipo de erro geralmente ocorre quando os dados na linha que está sendo adicionada não puderam ser convertidos em um tipo .NET Framework sem alguma perda de precisão.
Se ocorrer um erro durante uma Fill
operação, a linha atual não será adicionada ao DataTable
. O FillError
evento permite resolver o erro e adicionar a linha, ou ignorar a linha excluída e continuar a Fill
operação.
O FillErrorEventArgs
passado para o FillError
evento pode conter várias propriedades que permitem responder e resolver erros. A tabela a seguir mostra as propriedades do FillErrorEventArgs
objeto.
Property | Description |
---|---|
Errors |
O Exception que ocorreu. |
DataTable |
O DataTable objeto que está sendo preenchido quando o erro ocorreu. |
Values |
Uma matriz de objetos que contém os valores da linha que está sendo adicionada quando o erro ocorreu. As referências ordinais da Values matriz correspondem às referências ordinais das colunas da linha que está sendo adicionada. Por exemplo, Values[0] é o valor que estava sendo adicionado como a primeira coluna da linha. |
Continue |
Permite que você escolha se deseja ou não lançar uma exceção. Definir a Continue propriedade para false interromperá a operação atual Fill e uma exceção será lançada. Configuração Continue para true continuar a Fill operação apesar do erro. |
O exemplo de código a seguir adiciona um manipulador de eventos para o FillError
evento do DataAdapter
. No código do FillError
evento, o exemplo determina se há o potencial de perda de precisão, fornecendo a oportunidade de responder à exceção.
AddHandler adapter.FillError, New FillErrorEventHandler( _
AddressOf FillError)
Dim dataSet As DataSet = New DataSet
adapter.Fill(dataSet, "ThisTable")
Private Shared Sub FillError(sender As Object, _
args As FillErrorEventArgs)
If args.Errors.GetType() Is Type.GetType("System.OverflowException") Then
' Code to handle precision loss.
' Add a row to table using the values from the first two columns.
DataRow myRow = args.DataTable.Rows.Add(New Object() _
{args.Values(0), args.Values(1), DBNull.Value})
' Set the RowError containing the value for the third column.
myRow.RowError = _
"OverflowException encountered. Value from data source: " & _
args.Values(2)
args.Continue = True
End If
End Sub
adapter.FillError += new FillErrorEventHandler(FillError);
DataSet dataSet = new DataSet();
adapter.Fill(dataSet, "ThisTable");
protected static void FillError(object sender, FillErrorEventArgs args)
{
if (args.Errors.GetType() == typeof(System.OverflowException))
{
// Code to handle precision loss.
//Add a row to table using the values from the first two columns.
DataRow myRow = args.DataTable.Rows.Add(new object[]
{args.Values[0], args.Values[1], DBNull.Value});
//Set the RowError containing the value for the third column.
myRow.RowError =
"OverflowException Encountered. Value from data source: " +
args.Values[2];
args.Continue = true;
}
}