共用方式為


使用 DataAdapter 事件

ADO.NET DataAdapter 公開的三個事件可讓您用來回應資料來源中的資料變更。下列表格顯示 DataAdapter 事件。

事件 說明

RowUpdating

資料列上的 UPDATE、INSERT 或 DELETE 作業 (呼叫其中一個 Update 方法) 即將開始。

RowUpdated

資料列上的 UPDATE、INSERT 或 DELETE 作業 (呼叫其中一個 Update 方法) 已經完成。

FillError

Fill 作業過程中發生錯誤。

RowUpdating 和 RowUpdated

在資料來源中處理 DataSet 之資料列的任何更新之前,會引發 RowUpdating。而在資料來源處理任何對 DataSet 資料列的更新後,便會引發 RowUpdated。所以,您可以使用 RowUpdating 在更新發生前修改更新行為,讓您更能控制更新發生的時間、保留對已更新資料列的參考、取消目前更新、將更新排程於稍後進行批次處理等其他功能。RowUpdated 是回應更新過程中發生錯誤和例外狀況的好方法。您可以將錯誤資訊加入 DataSet 以及重試邏輯等等。

傳遞至 RowUpdatingRowUpdated 事件的 RowUpdatingEventArgsRowUpdatedEventArgs 引數包括:Command 屬性,參考用來執行更新作業的 Command 物件;Row 屬性,參考內含已更新資訊的 DataRow 物件;StatementType 屬性,指定執行的更新類型;TableMapping (如果有的話);和作業的 Status

您可以使用 Status 屬性來判斷作業期間是否發生錯誤,也可以依您的需要,控制目前和結果資料列的動作。發生事件時,Status 屬性即等於 ContinueErrorsOccurred。您可以將 Status 屬性設成下列表格所顯示的值,以控制更新期間的後續動作。

狀態 說明

Continue

繼續更新作業。

ErrorsOccurred

中止更新作業並擲回例外狀況。

SkipCurrentRow

忽略目前資料列並繼續更新作業。

SkipAllRemainingRows

中止更新作業但不擲回例外狀況。

若將 Status 屬性設為 ErrorsOccurred,則會擲回例外狀況。您可以將 Errors 屬性設定為您希望的例外狀況,以控制擲回的例外狀況。若將 Status 設為其他任一值,則可避免擲回例外狀況。

您也可以使用 ContinueUpdateOnError 屬性來處理更新資料列的錯誤。如果 DataAdapter.ContinueUpdateOnErrortrue,則當資料列的更新擲回例外狀況時,會將例外狀況的文字放入特定資料列的 RowError 資訊中,並繼續作業,而不擲回例外狀況。這樣一來,您可以在完成 Update 後才回應錯誤,而 RowUpdated 事件則是讓您在發生錯誤時立即回應該錯誤。

下列程式碼範例顯示如何加入和移除事件處理常式。RowUpdating 事件處理常式將所有的刪除資料錄和時間戳記寫入記錄檔。RowUpdated 事件處理常式會將錯誤資訊加入 DataSet 之資料列的 RowError 屬性中、隱藏例外狀況,並繼續作業 (與 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;
  }
}

FillError

Fill 作業期間發生錯誤時,DataAdapter 會發出 FillError 事件。當加入資料列中的資料必須放棄一些精確度,不然無法轉換為 .NET Framework 型別時,通常就會發生這類型的錯誤。

Fill 作業期間如果發生錯誤,則不會將目前的資料列加入 DataTableFillError 事件可讓您解析錯誤並加入資料列,或忽略排除的資料列,繼續進行 Fill 作業。

傳遞給 FillError 事件的 FillErrorEventArgs 可包含數個屬性,讓您回應並解決錯誤。下列表格顯示 FillErrorEventArgs 物件的屬性。

屬性 說明

Errors

所發生的例外狀況。

DataTable

發生錯誤時,填入的 DataTable 物件。

Values

發生錯誤時,包含加入資料列值的物件陣列。Values 陣列的序數參考對應至加入資料列資料行的序數參考。例如,Values[0] 便是當成資料列第一個資料行而加入的值。

Continue

可讓您選擇是否要擲回例外狀況。將 Continue 屬性設為 false,即可中斷目前的 Fill 作業,並擲回例外狀況。將 Continue 設為 true,則不管是否發生錯誤,都將繼續進行 Fill 作業。

下列程式碼範例為 DataAdapterFillError 事件加入事件處理常式。範例的 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.
    args.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.
    args.RowError = 
       "OverflowException Encountered. Value from data source: " +
       args.Values[2];
    args.Continue = true;
  }
}

請參閱

其他資源

使用 DataAdapters