代码之家  ›  专栏  ›  技术社区  ›  GuidoG

适配器。Update首先转到Rowupdated事件,然后再转到catch块

  •  1
  • GuidoG  · 技术社区  · 8 年前

    我有一个 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;
    }
    

    这是我的行更新事件

    void adapter_RowUpdated(object sender, SqlRowUpdatedEventArgs e)
    {
        if (e.StatementType == StatementType.Insert)
        {
           object ai = e.Command.Parameters["@SCOPE_ID"].Value;
           e.Row[_IdentityFieldName] = ai;
        }
    }
    

    一年多以来,这种做法一直很有效。
    但有时我在插入时会遇到一个异常“column xxxID cannot be null”,所以我对它进行了调试,问题是当 adapter.Update(table) 失败(例如,由于违反了检查约束),下一行代码不是Catch代码,但它首先进入RowUpdated事件。
    在这种情况下,会发生一个新的异常,即\u IdentityFieldName不能为null(它包含表的主字段的名称,这是一个标识字段)

    只有在这之后,它才会进入catch,但在那个时候,原始的异常被替换为 check constraint violated column cannot be null

    当我运行/调试时,会发生以下情况

    应用程序在 适配器。更新(表) 除此之外

    INSERT语句与CHECK约束冲突 “CK\U PrijsAankoop”。数据库“GTT\U测试”中发生冲突,表 “dbo.tblOpdrachtCar

    现在,我希望它进入catch,但它首先进入adapter\u RowUpdated事件,然后在该行中引发另一个异常 e.Row[IdentityFieldName] = ai;

    OpdrachtCarID“不允许Null

    现在它终于进入了catch块,但异常现在不再是原始异常了!

    所以我的问题是 ,如何强制dotnet执行正确的异常处理并直接转到捕获,而不首先转到此事件?

    1 回复  |  直到 8 年前
        1
  •  1
  •   Reza Aghaei    8 年前

    这是故意的。 RowUpdated 将在尝试更新行后引发,无论成功与否。事实上 行已更新 对于响应更新期间发生的错误和异常特别有用。

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

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

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

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

    推荐文章