Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用具有适当严重性的EF 6时从未发现RAISERROR_C#_Sql_Sql Server_Entity Framework_Stored Procedures - Fatal编程技术网

C# 使用具有适当严重性的EF 6时从未发现RAISERROR

C# 使用具有适当严重性的EF 6时从未发现RAISERROR,c#,sql,sql-server,entity-framework,stored-procedures,C#,Sql,Sql Server,Entity Framework,Stored Procedures,我觉得我将要放弃整个项目,重新开始,因为这会给我带来很多挫折。所以我非常感谢任何人的洞察力 我有SQL Server存储过程,需要执行某些逻辑检查才能继续。如果这些检查失败,将调用RAISERROR()并返回SP。以下是其中一项检查的示例: IF DATALENGTH(@LastName) < 2 BEGIN SELECT @err_msg = CONVERT(NVARCHAR(200), @LastName); RAISERROR('The "Single / Last

我觉得我将要放弃整个项目,重新开始,因为这会给我带来很多挫折。所以我非常感谢任何人的洞察力

我有SQL Server存储过程,需要执行某些逻辑检查才能继续。如果这些检查失败,将调用RAISERROR()并返回SP。以下是其中一项检查的示例:

IF DATALENGTH(@LastName) < 2
BEGIN
    SELECT @err_msg = CONVERT(NVARCHAR(200), @LastName);
    RAISERROR('The "Single / Last Name" param provided is too short: %s',16,1, @err_msg);
    RETURN;
END
现在我应该能够传递LastName=“”(或任何其他<2个字符)并返回带有上述RAISERROR文本的SqlException-但是我所能做的任何事情都没有让这个SqlException在应该触发时触发

到目前为止,我已经尝试了以下几点:

  • 使用THROW关键字,而不是简单地返回(未捕获任何内容)
  • 运行SQL Server Profiler,获取C#client发送的查询,并在SSMS中手动执行它(导致错误在输出中正确显示)
  • 修改生成的EF以在ExecuteFunction()行添加try/catch块(未捕获任何内容)

目前,大多数在线线程都会将严重性级别设置为16来修复问题,因此我不知道还应该设置或寻找什么…

我已经实现了一个解决方案,但它感觉不干净。此外,我不明白为什么我必须对生成的代码进行这些编辑才能捕获SqlException-如果有人有改进,我肯定会欢迎:

第1部分:确保在模型的“函数导入”下导入的函数设置为返回“none”集合作为选项。(我还没有找到返回对象的SP)

第2部分:将上面返回行中EF生成的函数代码修改为:

try
{
    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("CreatePendingContact", lastNameParameter);
}
catch (Exception ex)
{
    if (ex.InnerException is SqlException) { throw ex.InnerException; }
    else { throw; }
}

此更改将仅转发SqlExceptions,同时仍在本地引发所有其他异常。这是一个超级简单的例子,但到目前为止它似乎还有效…

当我使用您的示例代码执行测试过程时

IF DATALENGTH(@LastName) < 2
BEGIN
    SELECT @err_msg = CONVERT(NVARCHAR(200), @LastName);
    RAISERROR('The "Single / Last Name" param provided is too short: %s',16,1, @err_msg);
    RETURN;
END
如果数据长度(@LastName)<2
开始
选择@err_msg=CONVERT(NVARCHAR(200),@LastName);
RAISERROR('提供的“Single/Last Name”参数太短:%s',16,1,@err_msg);
返回;
结束
我的程序没有失败。当我像下面那样使用LTRIM和RTRIM时,它确实失败了

IF DATALENGTH(LTRIM(RTRIM(@LastName))) < 2
BEGIN
    SELECT @err_msg = CONVERT(NVARCHAR(200), @LastName);
如果数据长度(LTRIM(RTRIM(@LastName))<2
开始
选择@err_msg=CONVERT(NVARCHAR(200),@LastName);
RAISERROR('提供的“Single/Last Name”参数太短:%s',16,1,@err_msg); 结束

通过提供错误和干净执行的返回值,有一种更可靠的方法来编写过程。然后在.Net中获取返回值并对其进行评估。下面是经过修改的存储过程,以演示我的意思

CREATE Procedure dbo.TestError @LastName Char(10)
AS
BEGIN
DECLARE @err_msg nvarchar(200)
IF DATALENGTH(LTRIM(RTRIM(@LastName))) < 2
BEGIN
    SELECT @err_msg = CONVERT(NVARCHAR(200), @LastName);
    GOTO ErrorExit   
END

CleanExit:
BEGIN 
  RETURN 0
END

ErrorExit:
BEGIN
   RAISERROR('The "Single / Last Name" param provided is too short: %s',16,1, @err_msg);
    RETURN 1;
END
END
创建过程dbo.TestError@LastName Char(10)
作为
开始
声明@err_msg nvarchar(200)
如果数据长度(LTRIM(RTRIM(@LastName))<2
开始
选择@err_msg=CONVERT(NVARCHAR(200),@LastName);
转到错误出口
结束
清洁出口:
开始
返回0
结束
错误退出:
开始
RAISERROR('提供的“Single/Last Name”参数太短:%s',16,1,@err_msg);
返回1;
结束
结束

没错,EF为您的RAISEERROR抛出的不是您试图捕获的
SqlException
。请参阅
IF DATALENGTH(LTRIM(RTRIM(@LastName))) < 2
BEGIN
    SELECT @err_msg = CONVERT(NVARCHAR(200), @LastName);
CREATE Procedure dbo.TestError @LastName Char(10)
AS
BEGIN
DECLARE @err_msg nvarchar(200)
IF DATALENGTH(LTRIM(RTRIM(@LastName))) < 2
BEGIN
    SELECT @err_msg = CONVERT(NVARCHAR(200), @LastName);
    GOTO ErrorExit   
END

CleanExit:
BEGIN 
  RETURN 0
END

ErrorExit:
BEGIN
   RAISERROR('The "Single / Last Name" param provided is too short: %s',16,1, @err_msg);
    RETURN 1;
END
END