我目前正尝试使用实体框架(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
{
// ...
}
sp_
,使用其他前缀或根本不使用前缀! - undefined