adapter.Update首先进入Rowupdated事件,然后进入catch块

时间:2018-04-17 12:29:25

标签: c# .net winforms exception-handling ado.net

我有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执行正确的异常处理并直接进入捕获而不先进入此事件?

1 个答案:

答案 0 :(得分:1)

这是设计的。尝试更新行后,RowUpdated将会提升,无论失败是否成功。实际上,RowUpdated对于响应更新期间发生的错误和异常特别有用。

事件的事件参数SqlRowUpdatedEventArgs具有Errors属性,您可以使用该属性来获取行更新期间发生的错误。

您可以使用event参数的Status属性检查执行的状态:

if (e.Status == UpdateStatus.ErrorsOccurred)  
{  
    //An error occurred
}  

要了解有关DataAdapter事件的更多信息,请查看Handling DataAdapter Events