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;
}
}
另請參閱
- DataAdapter 和 DataReader
- 處理資料集事件
- 處理資料表事件
- 活動
- ADO.NET 概觀