实体框架 - 存储过程返回值

12

我正在尝试获取存储过程的返回值。以下是一个这样的存储过程示例:

select
    Name,
    IsEnabled
from
    dbo.something
where
    ID = @ID

if @@rowcount = 0
    return 1    

return

这是一个简单的查询。如果没有找到任何行,我的结果集将为null,但我仍然会有一个返回值。

这个例子不太好,因为这是一个查询,所以当然我可以查找是否返回了0行。然而,在插入、删除或其他调用中,我们需要这个返回值才能知道是否存在问题。我一直无法找到一种方法来获取这个返回值。我可以获取输出值,也可以获取结果集,但是没有返回值。

如果我手动调用SQL,甚至使用实体框架运行SqlCommand,我可以获取返回值,但这不是我想做的。

有人曾经能够使用实体框架从存储过程中获取返回值吗?

谢谢帮忙!


3
Entity Framework是一个ORM,它并不旨在完全替代应用程序中对数据库的所有调用。 - cadrell0
3
这是您的答案:“如果我手动调用SQL,甚至使用实体框架运行SQLCommand,我可以获得返回值。” - jrummell
@Lamak - 哎呀,我的错,我看到它低于50%,就以为最糟糕的情况发生了。 - William Dwyer
我已经成功使用Entity Framework 5(但我认为它从4.x版本开始就可以使用)使用Code First方法获取返回值(以及输出和输入参数)。从您的帖子中,我看不出您正在使用EF的哪个版本以及如何进行映射。如果您考虑在此处使用Code First方法,则可以在我的帖子中找到解决方案:https://dev59.com/bmUq5IYBdhLWcg3wKtRL - Daniele Armanasco
6个回答

6

我猜存储过程返回值的支持取决于Entity framework的版本。虽然直接返回值对我不起作用,但我成功地使用OUTPUT存储过程参数获取了值。例如:

USE [YOUR_DB_NAME]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[TestReturnValue]
    @InputValue int = 0,
    @Result int OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    SELECT @Result  = @InputValue
    RETURN(@InputValue);
END

这是测试代码:

void TestReturnValue()
{
    using (var db = new YourDBContext())
    {
        var result = new System.Data.Objects.ObjectParameter("Result", 0);
        Console.WriteLine("SP returned {0}", db.TestReturnValue(123, result));
        Console.WriteLine("Output param {0}", result.Value);
    }
}

这是输出结果:

SP returned -1
Output param 123

正如您所见,直接返回的值输出了一些垃圾,但是输出参数是有效的!

本文提供有关从 SP 返回值的两种常规信息

希望这可以帮助到您。


3

不,Entity Framework没有丰富的存储过程支持,因为它是一个ORM而不是SQL替代品。

正如您已经发现的那样,如果您需要使用存储过程的较少常见(更高级?)特性,则必须使用传统的ADO.NET。


2
补充一下:@@rowcount将返回一个标量值,或者说任何select @value都将返回一个标量值。如果您已经有了一个结果集,这将添加一个新的结果集。目前,4.0不支持多个结果集,但是带有EF的Framework 4.5将支持多个结果集。 - bugnuker

0
根据Hadi Salehy的回答,我编写了这段代码并且对我有效。 我的SP
CREATE PROCEDURE [schema].[ProcedureName]
@param1 int,
@param2 varchar(20),
@param3 varchar(50)
AS
UPDATE Table1
SET Field2 = @param2, Fiedl3 = @param3
WHERE (Field1 = @param1)
SELECT @@ROWCOUNT;

我的 C# 代码。

int quantity = await _context.Database.ExecuteSqlRawAsync("[schema].[ProcedureName] {0}, {1}, {2}", myModel.Param1, myModel.Param2, myModel.Param3);


0

你必须使用 "Context.Database.SqlQuery",并指定存储过程的输出类型。

        var spReturnVaue = Context.Database.SqlQuery<Type>("[schema].YourSp").FirstOrDefault();

        int firstId = Context.Database.SqlQuery<int>("[dbo].GetFirstId").FirstOrDefault();

0
var parms = new List<SqlParameter>
{
    new SqlParameter { ParameterName = "@Data", Value = date},
    new SqlParameter { 
        ParameterName = "@returnValue", 
        Value = -123, 
        SqlDbType = System.Data.SqlDbType.Int, 
        Direction = System.Data.ParameterDirection.Output
    }
};

var sql = "EXEC @returnValue = db.dbo.spDoSomething @Data;";
var retProc = await _context.Database.ExecuteSqlRawAsync(sql, parms.ToArray());

var returnValue = (int)parms[1].Value;

-2
为了在EF中获得所需的结果,您应该返回相同的结构(而不是1和Name、IsEnabled)。 在此查询中,您应该返回'',0作为if条件中的示例,而不是1:
select
    Name,
    IsEnabled
from
    dbo.something
where
    ID = @ID
if @@rowcount = 0 return '',0

1
这与问题有任何关系吗? - SQLMason

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