我有SqlDataAdapter
adapter.RowUpdated += adapter_RowUpdated;
try
{
try
{
adapter.Update(Table);
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw new Exception(ex.Message);
}
}
finally
{
adapter.RowUpdated -= adapter_RowUpdated;
}
这是我的Rowupdated事件
void adapter_RowUpdated(object sender, SqlRowUpdatedEventArgs e)
{
if (e.StatementType == StatementType.Insert)
{
object ai = e.Command.Parameters["@SCOPE_ID"].Value;
e.Row[_IdentityFieldName] = ai;
}
}
这已经有效了一年多了
但有时我在插入时得到一个异常“列xxxID不能为空”,所以我调试了它,问题是当adapter.Update(table)
失败时(例如因为违反了检查约束),下一行代码不是Catch代码,但它首先进入RowUpdated事件
在那种情况下,当然会发生一个新的异常,即_IdentityFieldName不能为空(它保存表的主要字段的名称,这是一个标识字段)
然后才进入捕获,但此时原始异常从check constraint violated
替换为column cannot be null
当我运行/调试时,会发生以下情况
应用程序在adapter.Update(table)
处中断,异常
INSERT语句与CHECK约束冲突 “CK_PrijsAankoop”。冲突发生在数据库“GTT_Test”表中 “dbo.tblOpdrachtCar
现在我希望它进入catch,但它首先进入adapter_RowUpdated事件,并在行e.Row[IdentityFieldName] = ai;
上抛出另一个异常
OpdrachtCarID'不允许空值
现在它终于进入了catch块,但异常现在不再是原来的例外了!
所以我的问题是,如何强制dotnet执行正确的异常处理并直接进入捕获而不先进入此事件?
答案 0 :(得分:1)
这是设计的。尝试更新行后,RowUpdated
将会提升,无论失败是否成功。实际上,RowUpdated
对于响应更新期间发生的错误和异常特别有用。
事件的事件参数SqlRowUpdatedEventArgs
具有Errors
属性,您可以使用该属性来获取行更新期间发生的错误。
您可以使用event参数的Status
属性检查执行的状态:
if (e.Status == UpdateStatus.ErrorsOccurred)
{
//An error occurred
}
要了解有关DataAdapter事件的更多信息,请查看Handling DataAdapter Events。