Entity framework 处理实体框架中的SQL异常
在我的sql存储过程中,我进行了一些插入和更新,在某些情况下会引发主键或唯一键冲突 当我尝试从ADO.net执行此过程时,.net应用程序也会抛出该异常,并让我知道发生了错误 但是当我试图从EF执行这个过程时,它只是执行。它既不显示任何内容,也不更新任何内容 我应该如何处理或通知用户发生了错误 Net代码是Entity framework 处理实体框架中的SQL异常,entity-framework,exception-handling,Entity Framework,Exception Handling,在我的sql存储过程中,我进行了一些插入和更新,在某些情况下会引发主键或唯一键冲突 当我尝试从ADO.net执行此过程时,.net应用程序也会抛出该异常,并让我知道发生了错误 但是当我试图从EF执行这个过程时,它只是执行。它既不显示任何内容,也不更新任何内容 我应该如何处理或通知用户发生了错误 Net代码是 SqlConnection sqlConnection = new SqlConnection(@"data source=database01; database=test; user
SqlConnection sqlConnection = new SqlConnection(@"data source=database01; database=test; user id=test; password=test;");
SqlCommand cmd = new SqlCommand("[uspUpdateTest]", sqlConnection);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("RunID", RunID);
cmd.Parameters.AddWithValue("RunCode", RunCode);
sqlConnection.Open();
var str = cmd.ExecuteNonQuery();
实体框架代码为
TestEntities context = new TestEntities();
var str=context.UpdateRun(RunID, RunCode);
对于优雅地捕获和处理异常,本文给出了一个很好的总结。在这之后,您有几个用于回滚等的选项。首先,确保您在存储过程中抛出了一个异常,我们可以在C#代码中捕获该异常。见--引述: 如果希望RAISERROR引发SqlException,则需要设置其 严重程度超过10。严重性为10及以下的错误为 信息性,因此不抛出异常 我还将向您展示以下代码。在使用实体框架从服务层获取数据时,我一直在MVC控制器中使用此功能:
try
{
try
{
//Entity Framework/Data operations that could throw the data exception
//...
} catch (DataException dex) //see http://msdn.microsoft.com/en-us/library/system.data.dataexception.aspx
{
//Specifically handle the DataException
//...
}
}
catch (Exception e)
{
//do something (logging?) for the generic exception
throw e;
}
如果第一个捕获没有触发,您可以在最后一个捕获上设置一个断点,以查看异常类型/内部异常“e”,并从那里开始。在泛型异常上设置断点是很有用的,因为它可以让我知道何时我没有处理某些事情。我非常确定,您必须在函数导入中设置一些返回类型(伪)。这在大多数情况下是有意义的,因为如果您不这样做,您的方法名称将不会出现在intellisense中,并且您将无法使用context.MethodName访问它 我的建议是,删除函数导入的返回类型并将其设置为无。使用上下文的ExecuteFunction方法执行您的方法
ExecuteFunction(函数名、参数)。它肯定会抛出异常。对于实体框架中sql引发的错误异常,我们可以使用以下方法: 比如说,我们有DBContext。所以
var connection= (SqlConnection)db.Database.Connection;
if (connection != null && connection.State == ConnectionState.Closed)
{
connection.Open();
}
SqlCommand com = new SqlCommand("spname", connection);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add(new SqlParameter("@parameter", parameter));
try
{
com.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex.message;
} `
调用代码?………您是否绝对确定EF代码应引发异常?您是否在调试模式下使用“抛出异常时中断”来运行此程序?Gert Arnold给出了很好的建议。您也可以在代码的早期放置断点,然后使用
f10
逐行跳过它(f11
,如果您想输入正在调用的方法)。问题不在于如何处理异常。这是因为它们似乎没有被抛出。代码不会捕获块,因为它不会抛出任何异常,这是sql存储过程引发的问题异常没有被追溯到实体FrameworkId。你看一下我在回答开始时发布的链接吗?如果没有任何异常,这可能是原因之一。修改存储过程以RAISERROR
开头(或创建一个新的测试过程),以便将错误引发机制测试回C#代码。一旦你让它工作起来,就把它注释掉,然后从那里开始。对不起,为了清楚起见,我在这里的意思是修改你的存储过程,使它总是抛出一个异常,然后使用你的C#代码调用SQL存储过程,以确保在你尝试捕获你的特定异常之前可以捕获任何异常。有关如何使用,请参阅。特别注意有关严重性的注释:在TRY…CATCH构造的TRY块中执行的RAISERROR严重性为11到19会导致控制转移到关联的CATCH块。您可能会发现此线程很有用-谢谢Aaron,但问题不在过程中,而是在我的函数导入中,我的过程没有返回任何东西,只是为了从EF中的上下文获取函数,我选择了一个伪返回类型,这导致了问题。MSingh的解决方案对我有效。感谢您的努力。:-)