Бөлісу құралы:


Пакетные операции с использованием объектов DataAdapter

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

Скачать ADO.NET

Поддержка пакетных операций в ADO.NET позволяет объекту DataAdapter группировать операции INSERT, UPDATE и DELETE из DataSet или DataTable к серверу вместо отправки за один раз одной операции. Уменьшение числа двусторонних передач сигнала на сервер обычно приводит к значительному повышению производительности. Пакетное обновление поддерживается поставщиком данных Microsoft SqlClient для SQL Server (Microsoft.Data.SqlClient).

При обновлении базы данных изменениями из объекта DataSet в более ранних версиях ADO.NET метод Update для DataAdapter выполняет обновления в базе данных по одной строке. Когда он просматривает строки в указанной таблице DataTable, он проверяет каждую строку DataRow, чтобы выявить, не была ли она изменена. Если строка изменена, он вызывает соответствующую команду UpdateCommand, InsertCommand или DeleteCommand в зависимости от значения свойства RowState для этой строки. Каждое обновление строки подразумевает сетевую двустороннюю передачу сигнала в базу данных.

В поставщике данных Microsoft SqlClient для SQL Server класс SqlDataAdapter предоставляет свойство UpdateBatchSize. При установке для свойства UpdateBatchSize положительного целого значения обновления базы данных посылаются как пакеты указанного размера. Например, при установке UpdateBatchSize в 10 производится группирование 10 отдельных инструкций и передача их как один пакет. При установке UpdateBatchSize в 0 SqlDataAdapter использует самой большой размер пакета, который может обработать сервер. При его установке в 1 отключаются пакетные обновления, т. к. строки посылаются по одной.

Примечание.

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

Использование свойства UpdateBatchSize

Если пакетные обновления включены, значение свойства UpdatedRowSource для UpdateCommand, InsertCommand и DeleteCommand объекта DataAdapter должно быть установлено в None или OutputParameters. При выполнении пакетного обновления значение свойства UpdatedRowSource команды для FirstReturnedRecord или Both недействительно.

Следующая процедура демонстрирует использование свойства UpdateBatchSize. Процедура принимает два аргумента, объект DataSet, который имеет столбцы, представляющие поля ProductCategoryID и Name в таблице Production.ProductCategory, и целое число, представляющее размер пакета (число строк в пакете). Код создает новый объект SqlDataAdapter, устанавливая его свойства UpdateCommand, InsertCommand и DeleteCommand. В коде предполагается, что объект DataSet имеет измененные строки. В нем устанавливается свойство UpdateBatchSize и выполняется обновление.

public static void BatchUpdate(DataTable dataTable, Int32 batchSize)
{
    // Assumes GetConnectionString() returns a valid connection string.
    string connectionString = GetConnectionString();

    // Connect to the AdventureWorks database.
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        // Create a SqlDataAdapter.  
        SqlDataAdapter adapter = new SqlDataAdapter();

        // Set the UPDATE command and parameters.  
        adapter.UpdateCommand = new SqlCommand(
            "UPDATE Production.ProductCategory SET "
            + "Name=@Name WHERE ProductCategoryID=@ProdCatID;",
            connection);
        adapter.UpdateCommand.Parameters.Add("@Name",
        SqlDbType.NVarChar, 50, "Name");
        adapter.UpdateCommand.Parameters.Add("@ProdCatID",
        SqlDbType.Int, 4, "ProductCategoryID");
        adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;

        // Set the INSERT command and parameter.  
        adapter.InsertCommand = new SqlCommand(
            "INSERT INTO Production.ProductCategory (Name) VALUES (@Name);",
            connection);
        adapter.InsertCommand.Parameters.Add("@Name",
        SqlDbType.NVarChar, 50, "Name");
        adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None;

        // Set the DELETE command and parameter.  
        adapter.DeleteCommand = new SqlCommand(
            "DELETE FROM Production.ProductCategory "
            + "WHERE ProductCategoryID=@ProdCatID;", connection);
        adapter.DeleteCommand.Parameters.Add("@ProdCatID",
        SqlDbType.Int, 4, "ProductCategoryID");
        adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None;

        // Set the batch size.  
        adapter.UpdateBatchSize = batchSize;

        // Execute the update.  
        adapter.Update(dataTable);
    }
}

DataAdapter имеет два события, связанные с обновлением: RowUpdating и RowUpdated. Дополнительные сведения см. в разделе Обработка событий DataAdapter.

Изменения в поведении событий при работе с пакетными обновлениями

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

Доступ к обновленным строкам

Если пакетная обработка отключена, доступ к обновляемой строке может быть выполнен при помощи свойства Row класса RowUpdatedEventArgs.

Если пакетная обработка включена для нескольких строк, формируется одно событие RowUpdated. Поэтому значение свойства Row для каждой из строк равно NULL. События RowUpdating по-прежнему вызываются для каждой строки. Метод CopyToRows класса RowUpdatedEventArgs позволяет обращаться к обработанным строкам, копируя ссылки на строки в массив. Если строки не обрабатываются, метод CopyToRows инициирует исключение ArgumentNullException. Свойство RowCount используется для возврата числа строк, обработанных перед вызовом метода CopyToRows.

Обработка ошибок данных

Пакетное выполнение оказывает то же влияние, что и выполнение каждой отдельной инструкции. Инструкции выполняются в порядке, который инструкции добавили в пакет. Ошибки обрабатываются в пакетном режиме, как если было бы при отключении пакетного режима. Каждая строка обрабатывается отдельно. Только успешно обработанные в базе данных строки будут обновлены в соответствующей строке DataRow таблицы DataTable.

Примечание.

Поставщик данных Microsoft SqlClient для SQL Server и внутренний сервер базы данных определяют, для каких конструкций SQL поддерживается пакетное выполнение. Если неподдерживаемая инструкция подается на выполнение, создается исключение.

См. также