C# 如何捕获实体框架4触发的RAISERROR调用引发的SqlException?

C# 如何捕获实体框架4触发的RAISERROR调用引发的SqlException?,c#,entity-framework-4,triggers,C#,Entity Framework 4,Triggers,我已设置实体框架来更新表。更新被instead of触发器拦截,该触发器调用RAISERROR: CREATE TRIGGER mySchema.UpdateBusinessObjects ON mySchema.BusinessObjects INSTEAD OF UPDATE AS RAISERROR(''test error from SQL'',16,1) RETURN 在我的repository类中,我试图捕获由SQL中的RAISERROR生成的SqlExceptio

我已设置实体框架来更新表。更新被instead of触发器拦截,该触发器调用RAISERROR:

CREATE TRIGGER mySchema.UpdateBusinessObjects
ON mySchema.BusinessObjects
INSTEAD OF UPDATE
AS
    RAISERROR(''test error from SQL'',16,1)
    RETURN
在我的repository类中,我试图捕获由SQL中的RAISERROR生成的SqlException:

public void SaveBusinessObject(BusinessObject b) {
    try {
         repo.Entry(b).State = EntityState.Modified;
         repo.SaveChanges();
    } catch (SqlException ex) {
         // handle exception here
    }
}
问题是C#没有捕获SqlException;它作为未处理的异常传递给调用方(“用户未处理SqlException:SQL测试错误”)。什么


看起来EF的SaveChanges()以某种方式将异常传递给了我的try-catch块。我曾尝试将catch语句切换为catch(Exception ex),以防EF异常更一般,但我仍然得到一个未处理的SqlException。我是不是错过了一些简单的东西?SaveChanges()方法有什么问题?

我知道避免一次尝试捕获的唯一方法是在不同的线程中发生异常。EF代码可以在不同的线程上执行吗?也许您可以在Exceptions(异常)对话框中以1º的概率启用异常抛出。

我尝试了与您在表上使用的触发器几乎完全相同的触发器,并尝试通过entity framework保存相应的(新)对象。从我所看到的,抛出的异常类型是System.Data.UpdateException,而不是SqlException。内部异常是SqlException,它确实包含您在触发器中引发的自定义消息,即“来自SQL的测试错误”。希望这有帮助

我确实遇到了这个问题

我使用MVC mini profiler分析查询时间。我发现如果我将其从项目中删除,那么异常就会像我预期的那样被捕获。

有两件事:-

  • 如果希望RAISERROR引发SqlException,则需要将其严重性设置为10以上。严重性为10及以下的错误是信息性错误,因此不会引发异常

  • 捕获实体异常 或者在常规异常的catch块中设置断点。在即时窗口中,检查异常的类型:ex.GetType()


  • 尝试使用一个空的catch,看看happensIt在这种情况下是什么样子的,在Visual Studio中调试模式下会显示两个异常:第一个是“System.Data.SqlClient.SqlException”,它没有被任何“catch()”类型语句捕获。第二个是“System.Data.Entity.Infrastructure.DbUpdateException”,由.NET捕获,并将前者作为InnerException包含。然而,只有后者导致.NET崩溃——第一个被忽略。是否前者来自外部进程,如SQL server?谢谢。。问题是,即使使用最基本的异常类型,我也无法捕获异常,因此我无法深入研究并找出它是什么类型。“从你所看到的”是什么意思?