Condividi tramite


Operazioni batch tramite DataAdapter

Si applica a: .NET Framework .NET .NET Standard

Scarica ADO.NET

Il supporto batch in ADO.NET consente a un tipo DataAdapter di raggruppare le operazioni INSERT, UPDATE e DELETE da un tipo DataSet o DataTable e di inviarle al server in batch, anziché inviare una singola operazione alla volta. La riduzione nel numero di percorsi di andata e ritorno al server determina in genere un notevole miglioramento delle prestazioni. L'aggiornamento batch è supportato per il provider di dati Microsoft SqlClient per SQL Server (Microsoft.Data.SqlClient).

Per l'aggiornamento di un database con modifiche provenienti da un DataSet, nelle versioni precedenti di ADO.NET il metodo Update di un DataAdapter eseguiva gli aggiornamenti del database una riga alla volta. Scorrendo le righe nella DataTable specificata, ciascuna riga DataRow veniva esaminata per rilevare eventuali modifiche. Se la riga era stata modificata, veniva chiamato il comando appropriato UpdateCommand, InsertCommand o DeleteCommand, in base al valore della proprietà RowState per quella determinata riga. Ogni aggiornamento di riga comportava un percorso di andata e ritorno in rete al database.

Nel provider di dati Microsoft SqlClient per SQL Server, SqlDataAdapter espone una proprietà UpdateBatchSize. Impostando UpdateBatchSize su un valore intero positivo, gli aggiornamenti vengono inviati al database come batch della dimensione specificata. Ad esempio, impostando UpdateBatchSize su 10, verranno raggruppate 10 istruzioni separate e inviate come singolo batch. Impostando UpdateBatchSize su 0, il SqlDataAdapter utilizzerà la dimensione di batch massima che il server è in grado di gestire. Se invece si imposta il valore su 1, gli aggiornamenti batch vengono disabilitati, in quanto le righe vengono inviate una alla volta.

Nota

Le prestazioni risulteranno ridotte se si esegue un batch di dimensioni molto elevate. Pertanto, prima di implementare l'applicazione è consigliabile verificare quale sia la dimensione ottimale per i batch.

Usare la proprietà UpdateBatchSize

Quando gli aggiornamenti batch sono abilitati, il valore della proprietà UpdatedRowSource dei comandi UpdateCommand, InsertCommand e DeleteCommand di Data Adapter deve essere impostato su None o su OutputParameters. Quando si esegue un aggiornamento batch, il valore UpdatedRowSource o FirstReturnedRecord della proprietà Both del comando non è valido.

Nella procedura seguente viene illustrato l'uso della proprietà UpdateBatchSize. La procedura accetta due argomenti, un oggetto DataSet contenente colonne che rappresentano i campi ProductCategoryID e Name della tabella Production.ProductCategory e un numero intero che rappresenta la dimensione del batch (il numero di righe nel batch). Il codice crea un nuovo oggetto SqlDataAdapter, impostandone le proprietà UpdateCommand, InsertCommand e DeleteCommand. Nel codice si presuppone che l'oggetto DataSet contenga righe modificate. La proprietà UpdateBatchSize viene impostata e viene eseguito l'aggiornamento.

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 include due eventi correlati all'aggiornamento: RowUpdating e RowUpdated. Per altre informazioni, vedere Gestire eventi DataAdapter.

Modifiche funzionali dell'evento con gli aggiornamenti batch

Quando l'elaborazione batch è abilitata, in un'unica operazione di database vengono aggiornate più righe. Pertanto, si verifica un solo evento RowUpdated per ogni batch, mentre l'evento RowUpdating si verifica per ogni riga elaborata. Quando l'elaborazione batch è disabilitata, i due eventi vengono generati con interfoliazione uno-a-uno, dove un evento RowUpdating e un evento RowUpdated vengono generati per una riga e un evento RowUpdating e un evento RowUpdated per la riga successiva, fino all'elaborazione di tutte le righe.

Accedere alle righe aggiornate

Quando l'elaborazione batch è disabilitata, è possibile accedere alla riga aggiornata mediante la proprietà Row della classe RowUpdatedEventArgs.

Quando l'elaborazione batch è abilitata, viene generato un unico evento RowUpdated per più righe. Pertanto, il valore della proprietà Row per ciascuna riga è null. Gli eventi RowUpdating vengono comunque generati per ogni riga. Il metodo CopyToRows della classe RowUpdatedEventArgs consente di accedere alle righe elaborate mediante la copia dei riferimenti alle righe in una matrice. Se non viene elaborata nessuna riga, CopyToRows genera un'eccezione ArgumentNullException. Usare la proprietà RowCount per restituire il numero di righe elaborate prima di chiamare il metodo CopyToRows.

Gestire gli errori relativi ai dati

I risultati dell'esecuzione batch sono identici a quelli ottenuti eseguendo le singole istruzioni una alla volta. Le istruzioni vengono eseguite nell'ordine in base al quale sono state aggiunte al batch. La gestione degli errori è la stessa sia in modalità batch sia quando la modalità batch è disabilitata. Ogni riga viene elaborata separatamente. Solo le righe che sono state elaborate correttamente nel database verranno aggiornate nell'oggetto DataRow corrispondente all'interno di DataTable.

Nota

Il provider di dati Microsoft SqlClient per SQL Server e il server di database back-end determinano i costrutti SQL supportati per l'esecuzione batch. Se per l'esecuzione viene inviata un'istruzione non supportata, è possibile che venga generata un'eccezione.

Vedi anche