Поделиться через


Обработка событий DataAdapter

ADO.NET DataAdapter предоставляет три события, которые можно использовать для реагирования на изменения, внесенные в данные в источнике данных. В следующей DataAdapter таблице показаны события.

Событие Описание
RowUpdating Операция UPDATE, INSERT или DELETE в строке (вызовом одного из Update методов) скоро начнется.
RowUpdated Операция UPDATE, INSERT или DELETE в строке (вызовом одного из Update методов) завершена.
FillError Произошла ошибка во время выполнения Fill операции.

RowUpdating и RowUpdated

RowUpdating вызывается перед обработкой любого обновления строки на DataSet источнике данных. RowUpdated вызывается после обработки любого обновления строки из источника данных DataSet. В результате можно использовать RowUpdating для изменения поведения обновления, прежде чем это произойдет, чтобы обеспечить дополнительную обработку при возникновении обновления, сохранить ссылку на обновленную строку, отменить текущее обновление и запланировать его для обработки пакетного процесса позже и т. д. RowUpdated необходимо для реагирования на ошибки и исключения, возникающие во время обновления. В нее можно добавить сведения об ошибке, а также логику DataSetповторных попыток и т. д.

Аргументы RowUpdatingEventArgs и RowUpdatedEventArgs, переданные в события RowUpdating и RowUpdated, включают следующее: свойство Command, которое ссылается на объект Command, используемый для выполнения обновления; свойство Row, которое ссылается на объект DataRow, содержащий обновленные сведения; свойство StatementType, определяющее тип выполняемого обновления; TableMapping, если применимо; и Status операции.

Свойство Status можно использовать для определения того, произошла ли ошибка во время операции, и при необходимости управлять действиями в отношении текущих и результирующих строк. При возникновении события свойство Status равно либо Continue либо ErrorsOccurred. В следующей таблице показаны значения, для которых можно задать Status свойство для управления последующими действиями во время обновления.

Состояние Описание
Continue Продолжайте операцию обновления.
ErrorsOccurred Прервать операцию обновления и вызвать исключение.
SkipCurrentRow Пропустить текущую строку и продолжить операцию обновления.
SkipAllRemainingRows Отмените операцию обновления, но не вызывайте исключение.

Установка свойства Status на ErrorsOccurred приводит к генерации исключения. Вы можете контролировать, какое исключение создается, задав Errors свойство требуемому исключению. Использование одного из других значений для Status предотвращает возникновение исключения.

Вы также можете использовать ContinueUpdateOnError свойство для обработки ошибок обновленных строк. Если DataAdapter.ContinueUpdateOnErrortrue, и обновление строки приводит к бросанию исключения, текст исключения помещается в RowError информацию конкретной строки, а обработка продолжается без выбрасывания исключения. Это позволяет реагировать на ошибки, когда Update завершено, в отличие от события RowUpdated, которое позволяет реагировать на ошибки при обнаружении ошибки.

В следующем примере кода показано, как добавлять и удалять обработчики событий. Обработчик RowUpdating событий записывает журнал всех удаленных записей с меткой времени. Обработчик RowUpdated событий добавляет сведения об RowError ошибке в свойство строки в DataSetстроке, подавляет исключение и продолжает обработку (зеркальное отображение поведения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;  
  }  
}  

Ошибка заполнения

DataAdapter вызывает событие FillError при возникновении ошибки во время Fill операции. Этот тип ошибки часто возникает, когда данные в добавляемой строке не могут быть преобразованы в тип .NET Framework без некоторой потери точности.

Если во время выполнения операции Fill возникает ошибка, текущая строка не добавляется в DataTable. Событие FillError позволяет устранить ошибку и добавить строку или игнорировать исключенную строку и продолжить Fill операцию.

FillErrorEventArgs, переданное событию FillError, может содержать несколько свойств, которые позволяют реагировать на ошибки и устранять их. В следующей FillErrorEventArgs таблице показаны свойства объекта.

Недвижимость Описание
Errors Произошло это Exception.
DataTable Объект DataTable заполнялся, когда произошла ошибка.
Values Массив объектов, содержащих значения строки, добавляемой при возникновении ошибки. Порядковые ссылки массива Values соответствуют порядковым ссылкам столбцов строки, которая добавляется. Например, Values[0] — это значение, которое было добавлено в качестве первого столбца строки.
Continue Позволяет выбрать, следует ли создавать исключение. Установка свойства Continue на false приведет к остановке текущей операции Fill и будет вызвано исключение. Установка Continue на true продолжает Fill операцию, несмотря на ошибку.

В следующем примере кода добавляется обработчик событий для FillError события DataAdapter. В коде события FillError например определяется, существует ли возможность потери точности, и при этом предоставляется возможность реагировать на исключение.

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;  
  }  
}  

См. также