Dela via


Hantera DataAdapter-händelser

ADO.NET DataAdapter exponerar tre händelser som du kan använda för att svara på ändringar som gjorts i datakällan. I följande tabell visas DataAdapter händelserna.

Händelse beskrivning
RowUpdating En uppdaterings-, INSERT- eller DELETE-åtgärd på en rad (med ett anrop till någon av Update metoderna) håller på att påbörjas.
RowUpdated En uppdaterings-, INSERT- eller DELETE-åtgärd på en rad (med ett anrop till någon av metoderna) har slutförts Update .
FillError Ett fel har uppstått under en Fill åtgärd.

RowUpdating och RowUpdated

RowUpdating genereras innan någon uppdatering till en rad från DataSet har bearbetats i datakällan. RowUpdated genereras efter att en uppdatering till en rad från DataSet har bearbetats i datakällan. Därför kan du använda RowUpdating för att ändra uppdateringsbeteendet innan det inträffar, för att tillhandahålla ytterligare hantering när en uppdatering inträffar, för att behålla en referens till en uppdaterad rad, avbryta den aktuella uppdateringen och schemalägga den för att en batchprocess ska bearbetas senare och så vidare. RowUpdated är användbart för att svara på fel och undantag som inträffar under uppdateringen. Du kan lägga till felinformation i DataSet, samt omförsökslogik och så vidare.

Argumenten RowUpdatingEventArgs och RowUpdatedEventArgs som skickas till händelserna och RowUpdated innehåller följande: en Command egenskap som refererar Command till objektet som används för att utföra uppdateringen, en Row egenskap som refererar DataRow till RowUpdating objektet som innehåller den uppdaterade informationen, en StatementType egenskap för vilken typ av uppdatering som utförs, TableMapping, om tillämpligt, och Status för åtgärden.

Du kan använda Status egenskapen för att avgöra om ett fel har inträffat under åtgärden och, om så önskas, för att kontrollera åtgärderna mot de aktuella och resulterande raderna. När händelsen inträffar är egenskapen Status lika med antingen Continue eller ErrorsOccurred. I följande tabell visas de värden som du kan ange Status egenskapen till för att styra senare åtgärder under uppdateringen.

Status beskrivning
Continue Fortsätt uppdateringsåtgärden.
ErrorsOccurred Avbryt uppdateringsåtgärden och utlöser ett undantag.
SkipCurrentRow Ignorera den aktuella raden och fortsätt uppdateringsåtgärden.
SkipAllRemainingRows Avbryt uppdateringsåtgärden men utlöser inget undantag.

Om du ställer in egenskapen StatusErrorsOccurred genereras ett undantag. Du kan styra vilket undantag som genereras genom att ange Errors egenskapen till önskat undantag. Om du använder något av de andra värdena för Status förhindras ett undantag från att genereras.

Du kan också använda egenskapen ContinueUpdateOnError för att hantera fel för uppdaterade rader. Om DataAdapter.ContinueUpdateOnError är true, när en uppdatering av en rad resulterar i ett undantag som utlöses, placeras texten i undantaget i RowError informationen för den specifika raden, och bearbetningen fortsätter utan att utlösa ett undantag. På så sätt kan du svara på fel när den Update är klar, till skillnad från RowUpdated händelsen, vilket gör att du kan svara på fel när felet påträffas.

Följande kodexempel visar hur du både lägger till och tar bort händelsehanterare. Händelsehanteraren RowUpdating skriver en logg över alla borttagna poster med en tidsstämpel. Händelsehanteraren RowUpdated lägger till felinformation till RowError egenskapen för raden i DataSet, undertrycker undantaget och fortsätter bearbetningen (spegling av beteendet för = ContinueUpdateOnErrortrue ).

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

FillError

Problem DataAdapter med händelsen FillError när ett fel inträffar under en Fill åtgärd. Den här typen av fel inträffar ofta när data i raden som läggs till inte kunde konverteras till en .NET Framework-typ utan någon förlust av precision.

Om ett fel inträffar under en Fill åtgärd läggs inte den aktuella raden till i DataTable. Med FillError händelsen kan du lösa felet och lägga till raden, eller ignorera den exkluderade raden och fortsätta åtgärden Fill .

Det FillErrorEventArgs som skickas FillError till händelsen kan innehålla flera egenskaper som gör att du kan svara på och lösa fel. I följande tabell visas objektets FillErrorEventArgs egenskaper.

Property beskrivning
Errors Det Exception inträffade.
DataTable Objektet DataTable fylls i när felet inträffade.
Values En matris med objekt som innehåller värdena för raden som läggs till när felet inträffade. Matrisens Values ordningsreferenser motsvarar ordningsreferenserna för kolumnerna i raden som läggs till. Är till exempel Values[0] det värde som lades till som den första kolumnen på raden.
Continue Gör att du kan välja om du vill utlösa ett undantag eller inte. Om du anger egenskapen Continue till false stoppas den aktuella Fill åtgärden och ett undantag genereras. Inställningen Continue för att true fortsätta Fill åtgärden trots felet.

Följande kodexempel lägger till en händelsehanterare för FillError händelsen för DataAdapter. FillError I händelsekoden avgör exemplet om det finns risk för precisionsförlust, vilket ger möjlighet att svara på undantaget.

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

Se även