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

Область применения: .NET Framework .NET .NET Standard

Скачать ADO.NET

Поставщик данных Microsoft SqlClient для SQL Server SqlDataAdapter предоставляет три события, которые можно использовать для реагирования на изменения, вносимые в данные в источнике данных. В следующей таблице показаны события 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.ContinueUpdateOnError имеет значение true, когда обновление строки приводит к возникновению исключения, то текст исключения помещается в сведения RowError для конкретной строки, и обработка продолжается без вызова исключения. Это позволяет реагировать на ошибки, когда Update завершено, в отличие от события RowUpdated, которое позволяет реагировать на ошибки при их возникновении.

В следующем образце кода показано, как добавлять и удалять обработчики событий. Обработчик события RowUpdating ведет журнал всех удаленных записей с временной меткой. Обработчик события RowUpdated добавляет сведения об ошибке в свойство RowError строки в DataSet, подавляет исключение и продолжает обработку (зеркально отображая поведение ContinueUpdateOnError = true).

static DataSet DataAdapterEventsDemo(SqlConnection connection, DataSet custDS)
{
    // Assumes that connection is a valid SqlConnection object 
    // and custDS includes the Customers table.
    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);

    return custDS;
}

protected static void OnRowUpdating(object sender, SqlRowUpdatingEventArgs args)
{
    if (args.StatementType == StatementType.Delete)
    {
        // Saves the removing rows with additional information in a file.
        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)
    {
        // Adds the error message to the row and skips from it.
        args.Row.RowError = args.Errors.Message;
        args.Status = UpdateStatus.SkipCurrentRow;
    }
}

Событие FillError

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

Если ошибка возникает во время операции 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 данный пример определяет потенциальную потерю точности, предоставляя возможность выполнить определенные действия в ответ на исключение.

static DataSet DataAdapterFillAndError(SqlDataAdapter adapter)
{
    // Assuemes adapter is a valid SqlDataAdapter object.
    adapter.FillError += new FillErrorEventHandler(FillError);

    DataSet dataSet = new DataSet();
    adapter.Fill(dataSet);
    return dataSet;
}

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