我觉得我要废弃整个项目并重新开始,因为这给我带来了挫折感。所以我非常感谢任何人的见解......
我有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
使用EF 6 model-first将此SP导入到C#项目中。 SP将导入模型的“函数导入”部分。导入上述SP的示例(简化参数):
public virtual ObjectResult<Nullable<int>> CreatePendingContact(string lastName)
{
var lastNameParameter = lastName != null ?
new ObjectParameter("LastName", lastName) :
new ObjectParameter("LastName", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable<int>>("CreatePendingContact", lastNameParameter);
}
可以在C#代码中调用此函数,并调用try / catch块(其中_model是EF生成的dbContext子类):
try
{
var result = _model.CreatePendingContact(
LastName
);
}
catch (SqlException ex)
{
Debug.WriteLine(ex.Message);
throw;
}
现在我应该可以传递LastName =&#34;&#34; (或其他任何&lt; 2 chars)并使用上面的RAISERROR文本返回一个SqlException - 但我能做的任何事情都没有触发它的SqlException!
到目前为止,这是我尝试过的事情:
现在,大多数在线主题都会将严重性级别设置为16来解决问题,因此我不知道应该设置或寻找的其他内容...
答案 0 :(得分:0)
这是我实施的解决方案,但感觉不干净。此外,我不明白为什么我必须对生成的代码进行这些编辑才能捕获SqlException - 如果有人有改进,那肯定会受到欢迎:
第1部分:确保将模型的“函数导入”下的导入函数设置为返回“无”的集合作为选项。 (我还没有得到返回对象的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,同时仍在本地抛出所有其他异常。这是一个超级简单的案例,但到目前为止似乎有效......
答案 1 :(得分:0)
当我使用您的示例代码进行测试时
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
我的过程没有失败。当我像下面那样使用LTRIM和RTRIM时它确实失败了
IF DATALENGTH(LTRIM(RTRIM(@LastName))) < 2
BEGIN
SELECT @err_msg = CONVERT(NVARCHAR(200), @LastName);
RAISERROR(提供的“单个/姓氏”参数太短:%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