語言

處理 DataAdapter 事件

DataAdapter ADO.NET 會公開三個事件,可用來響應數據源數據所做的變更。 下表顯示 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)。

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

填充錯誤

DataAdapter 在FillError操作中發生錯誤時,會發出Fill事件。 當加入的數據行中的數據無法轉換成 .NET Framework 類型而失去精確度時,通常會發生這種錯誤。

如果在操作期間發生 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 ,此範例會判斷是否有精確度遺失的可能性,並提供回應例外狀況的機會。

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

另請參閱