使用Entity Framework,我应该在存储过程中使用RETURN还是SELECT?

3

我目前正尝试使用实体框架(Entity Framework)与存储过程(stored procedures)一起使用,遇到了返回类型的问题。

我的存储过程的返回类型是BIT。

以下是我存储过程的简化代码:

CREATE PROCEDURE [dbo].[sp_makeStuff]
    @id int
AS
    BEGIN
        DECLARE @status BIT

        BEGIN TRY
            BEGIN TRANSACTION

            DELETE FROM MyTable WHERE Id = @id
            SET @status = 1

            COMMIT
        END TRY
        BEGIN CATCH
            SET @status = 0
            ROLLBACK
        END CATCH 

        RETURN @status

    END 
END

我在我的 .edmx 文件中添加了一个返回类型为 bool? 的 sp_makeStuff。

然后,我尝试使用以下代码执行它:

using (var ctx = new MyEntities())
{
    ObjectResult<bool?> result = ctx.sp_makeStuff(id);
    if (result.FirstOrDefault().Value) 
    {
        // Stuff
    }   
}

然而,它引发了一个类型为System.Data.EntityCommandExecutionException的异常,其消息是“存储数据提供程序返回的数据读取器没有足够的列来执行所请求的查询。”
经过一些调查,我发现如果我替换

RETURN @status

by

SELECT @status

过去,我总是使用T-SQL的“RETURN”关键字来返回这样的结果。
我想知道我的新实现是否正确。 因为我想在我的项目中使用EF,有没有一种方法使它与“RESULT”一起工作,或者我必须明确使用“SELECT”?
谢谢。
编辑24/10/2014
根据下面的回复,我重新编写了存储过程。不再返回结果,而是在出现问题时引发错误。
CREATE PROCEDURE [dbo].[sp_makeStuff]
    @id int
AS
    BEGIN

        BEGIN TRY
            BEGIN TRANSACTION

            DELETE FROM MyTable WHERE Id = @id

            COMMIT
        END TRY
        BEGIN CATCH
            ROLLBACK
            RAISERROR('Delete failed', 16, -1)
        END CATCH 

    END 
END

然后,我告诉EF我的存储过程不返回任何内容,如果有RAISERROR调用,我会处理异常。

try
{
    ctx.sp_web_DeleteElement(elementId);
    // ...
}
catch (Exception e) // Message in e.InnerException.Message
{
    // ...
}

我认为使用EF的最佳方式是使用输出参数来返回代码。或者,这个解决方法可能有所帮助? - undefined
3
提示:不应该为您的存储过程使用“sp_”前缀。 Microsoft已将该前缀保留给自己使用(请参见“命名存储过程”),而您未来可能会遇到名称冲突的风险。 还会影响存储过程的性能。最好是避免使用sp_,使用其他前缀或根本不使用前缀! - undefined
感谢这个提示 @marc_s。幸运的是,我们的项目只有400个以sp_前缀命名的存储过程 :D - undefined
1个回答

4
过去,我总是使用T-SQL“RETURN”关键字来返回这样的结果。
存储过程的返回代码只能是整数。它的目的是向调用应用程序指示成功或失败,而不是返回数据。使用OUTPUT参数或结果集返回数据。
返回值约定是零表示成功,非零表示错误/警告。非零值也可以用于指示特定原因(例如,在更新尝试期间找不到客户时使用99作为替代选项) ,而不是引发错误。默认情况下,如果引发了任何严重程度为10或更高的错误,SQL Server将返回负值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接