Utilizzo di eventi DataAdapter
DataAdapter di ADO.NET espone tre eventi che è possibile utilizzare per rispondere alle modifiche apportate ai dati nell'origine dati. Nella tabella riportata di seguito sono elencati gli eventi di DataAdapter.
Evento | Descrizione |
---|---|
RowUpdating | Sta per iniziare un'operazione UPDATE, INSERT o DELETE su una riga tramite la chiamata a uno dei metodi Update. |
RowUpdated | È stata completata un operazione UPDATE, INSERT o DELETE su una riga tramite la chiamata a uno dei metodi Update. |
FillError | Si è verificato un errore durante un'operazione Fill. |
RowUpdating e RowUpdated
RowUpdating viene generato prima che qualsiasi aggiornamento a una riga del DataSet sia stato elaborato nell'origine dati. RowUpdated viene generato dopo che gli aggiornamenti a una riga del DataSet sono stati elaborati nell'origine dati. È quindi possibile utilizzare RowUpdating per modificare il comportamento dell'aggiornamento prima che venga eseguito, per fornire una gestione aggiuntiva quando verrà eseguito l'aggiornamento, per conservare un riferimento a una riga aggiornata, per annullare l'aggiornamento corrente e pianificarlo per un processo batch che verrà eseguito successivamente e così via. RowUpdated è utile per rispondere agli errori e alle eccezioni che vengono generati durante l'aggiornamento. È possibile aggiungere le informazioni sugli errori al DataSet così come riprovare la logica e così via.
Gli argomenti RowUpdatingEventArgs e RowUpdatedEventArgs passati agli eventi RowUpdating e RowUpdated includono una proprietà Command che fa riferimento all'oggetto Command utilizzato per eseguire l'aggiornamento, una proprietà Row che fa riferimento all'oggetto DataRow contenente le informazioni aggiornate, una proprietà StatementType per il tipo di aggiornamento che viene eseguito, TableMapping, se applicabile, e la proprietà Status dell'operazione.
È possibile utilizzare la proprietà Status per determinare se si è verificato un errore durante l'operazione e, se lo si desidera, per controllare le operazioni relative alle righe correnti e risultanti. Quando si verifica l'evento, la proprietà Status sarà uguale a Continue o ErrorsOccurred. Nella tabella riportata di seguito sono indicati i valori su cui è possibile impostare la proprietà Status per controllare le operazioni successive durante l'aggiornamento.
Stato | Descrizione |
---|---|
Continue | Continua l'operazione di aggiornamento. |
ErrorsOccurred | Interrompe l'operazione di aggiornamento e genera un'eccezione. |
SkipCurrentRow | Ignora la riga corrente e continua l'operazione di aggiornamento. |
SkipAllRemainingRows | Interrompe l'operazione di aggiornamento, ma non genera un'eccezione. |
Se si imposta la proprietà Status su ErrorsOccurred, verrà generata un'eccezione. È possibile controllare l'eccezione che viene generata impostando la proprietà Errors sull'eccezione desiderata. Se si utilizza uno degli altri valori di Status non verrà generata alcuna eccezione.
È possibile anche utilizzare la proprietà ContinueUpdateOnError per gestire gli errori relativi alle righe aggiornate. Se DataAdapter.ContinueUpdateOnError è true, quando un aggiornamento su una riga determina la generazione di un'eccezione, il testo dell'eccezione viene inserito nelle informazioni RowError della stessa riga e l'elaborazione continua senza generare un'eccezione. In questo modo è possibile rispondere agli errori quando l'evento Update è completato, a differenza dell'evento RowUpdated che consente di rispondere agli errori nel momento in cui si verificano.
Nell'esempio di codice seguente viene illustrato come aggiungere e rimuovere i gestori eventi. Il gestore di eventi RowUpdating scrive un log di tutti i record eliminati con un timestamp. Il gestore di eventi RowUpdated aggiunge le informazioni sugli errori alla proprietà RowError della riga nel DataSet, evita la visualizzazione dell'eccezione e continua l'elaborazione, riproducendo quindi il comportamento di ContinueUpdateOnError = true.
Dim custDA As SqlDataAdapter = New SqlDataAdapter("SELECT CustomerID, CompanyName FROM Customers", nwindConn)
' Add handlers.
AddHandler custDA.RowUpdating, New SqlRowUpdatingEventHandler(AddressOf OnRowUpdating)
AddHandler custDA.RowUpdated, New SqlRowUpdatedEventHandler(AddressOf OnRowUpdated)
' Set DataAdapter command properties, fill the DataSet, and modify the DataSet.
custDA.Update(custDS, "Customers")
' Remove handlers.
RemoveHandler custDA.RowUpdating, New SqlRowUpdatingEventHandler(AddressOf OnRowUpdating)
RemoveHandler custDA.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
[C#]
SqlDataAdapter custDA = new SqlDataAdapter("SELECT CustomerID, CompanyName FROM Customers", nwindConn);
// Add handlers.
custDA.RowUpdating += new SqlRowUpdatingEventHandler(OnRowUpdating);
custDA.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
// Set DataAdapter command properties, fill the DataSet, and modify the DataSet.
custDA.Update(custDS, "Customers");
// Remove handlers.
custDA.RowUpdating -= new SqlRowUpdatingEventHandler(OnRowUpdating);
custDA.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
DataAdapter genera l'evento FillError quando si verifica un errore durante un'operazione Fill. Questo tipo di errore si verifica solitamente quando i dati nella riga che viene aggiunta non possono essere convertiti in un tipo .NET Framework senza una perdita di precisione.
Se si verifica un errore durante un'operazione Fill, la riga corrente non verrà aggiunta a DataTable. L'evento FillError consente di risolvere l'errore e aggiungere la riga o di ignorare la riga esclusa e continuare l'operazione Fill.
FillErrorEventArgs passato all'evento FillError può contenere diverse proprietà che consentono di rispondere agli errori e di risolverli. Nella tabella riportata di seguito vengono illustrate le proprietà dell'oggetto FillErrorEventArgs.
Proprietà | Descrizione |
---|---|
Errors | Exception generata. |
DataTable | Oggetto DataTable in fase di riempimento quando si è verificato l'errore. |
Values | Matrice di oggetti contenente i valori della riga in fase di inserimento quando si è verificato l'errore. I riferimenti ordinali della matrice Values corrispondono ai riferimenti ordinali delle colonne della riga che viene aggiunta. Values[0], ad esempio, è il valore che era stato aggiunto come prima colonna della riga. |
Continue | Consente di scegliere se generare o meno una Exception. Se si imposta la proprietà Continue su false, verrà interrotta l'operazione Fill corrente e verrà generata un'eccezione. Se si imposta Continue su true, l'operazione Fill continuerà nonostante l'errore. |
Nell'esempio di codice seguente viene aggiunto un gestore eventi per l'evento FillError di DataAdapter. Nel codice dell'evento FillError viene determinato se esiste il rischio potenziale di una perdita di precisione e viene prevista la possibilità di rispondere all'eccezione.
AddHandler myDA.FillError, New FillErrorEventHandler(AddressOf FillError)
Dim myDS As DataSet = New DataSet
myDA.Fill(myDS, "MyTable")
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.
args.RowError = "OverflowException Encountered. Value from data source: " & args.Values(2)
args.Continue = True
End If
End Sub
[C#]
myDA.FillError += new FillErrorEventHandler(FillError);
DataSet myDS = new DataSet();
myDA.Fill(myDS, "MyTable");
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.
args.RowError = "OverflowException Encountered. Value from data source: " + args.Values[2];
args.Continue = true;
}
}
Vedere anche
Utilizzo di provider di dati .NET Framework per accedere ai dati | Classe SqlRowUpdatedEventArgs | Classe SqlRowUpdatingEventArgs | Classe OleDbRowUpdatedEventArgs | Classe OleDbRowUpdatingEventArgs | Classe OdbcRowUpdatedEventArgs | Classe OdbcRowUpdatingEventArgs | Classe FillErrorEventArgs