使用Dapper.net调用存储过程,总是返回-1

qin*_*126 8 sql-server stored-procedures sql-server-2008 dapper

这是我的存储过程.当我测试它时,总是得到正确的结果.

ALTER PROCEDURE [dbo].[AddSmoothieIngredients]
    -- Add the parameters for the stored procedure here
    @Query NVARCHAR(4000) ,
    @SmoothieId INT ,
    @CreatedDate DATETIME ,
    @Status INT ,
    @UserId INT
AS 
    BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
        SET NOCOUNT ON;

        BEGIN TRY
            BEGIN TRAN

            IF @SmoothieId > 0 
                BEGIN
                    DELETE  FROM dbo.SmoothieIngredients
                    WHERE   SmoothieId = @SmoothieId;

                    EXECUTE (@Query);
                END
            ELSE 
                BEGIN

                    IF @UserId = 0 
                        SET @UserId = NULL;

                    INSERT  INTO dbo.Smoothie
                            ( Name, CreatedDate, Status, UserId )
                    VALUES  ( N'', @CreatedDate, @Status, @UserId );

                    SET @SmoothieId = SCOPE_IDENTITY();

                    SET @Query = REPLACE(@Query, 'sId', @SmoothieId);
                    EXECUTE (@Query);

                END 


            COMMIT TRAN

            RETURN @SmoothieId

        END TRY

        BEGIN CATCH
            ROLLBACK
        END CATCH

    END
Run Code Online (Sandbox Code Playgroud)

但是,当我使用dapper.net调用此存储过程时,始终返回-1.

        using (var conn = OpenConnection())
        {
            var parameter = new { Query = query, SmoothieId = smoothieId, CreatedDate = createdDate, Status = status, UserId = userId  };
            return conn.Execute("AddSmoothieIngredients", parameter, commandType: CommandType.StoredProcedure);
        }
Run Code Online (Sandbox Code Playgroud)

也许,dapper.net无法从存储过程中获取返回值.但我真的不知道如何解决它.请帮忙.

小智 16

因此,Execute()返回-1的原因是因为你的sproc SET NOCOUNT ON;根据这个问题 "抑制了"xx行受影响的"任何DML之后的消息" .是否要禁用该功能是该链接中还讨论的另一个问题.

我刚刚遇到同样的问题,所以我想我会投入2美分.


qin*_*126 13

找到解决方案,这是我在网上找到的示例代码.它的工作原理.

var p = new DynamicParameters();
p.Add("@a", 11);
p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

cnn.Execute("spMagicProc", p, commandType: commandType.StoredProcedure); 

int b = p.Get<int>("@b");
int c = p.Get<int>("@c"); 
Run Code Online (Sandbox Code Playgroud)


Zep*_*eph 2

看起来 Dapper.net 使用 SqlCommand.ExecuteNonQuery 作为 Execute 方法。这将返回受影响的行数,而不是 return 语句的值。您正在寻找的是Query

return connection.Query<int>("AddSmoothieIngredients", parameter, commandType: CommandType.StoredProcedure).First();
Run Code Online (Sandbox Code Playgroud)

尽管我认为这也不会捕获 return 语句,在这种情况下,您需要更改存储过程以返回结果集。

ALTER PROCEDURE [dbo].[AddSmoothieIngredients]
    -- Add the parameters for the stored procedure here
    @Query NVARCHAR(4000) ,
    @SmoothieId INT ,
    @CreatedDate DATETIME ,
    @Status INT ,
    @UserId INT
AS 
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
    SET NOCOUNT ON;

    BEGIN TRY
        BEGIN TRAN

        IF @SmoothieId > 0 
            BEGIN
                DELETE  FROM dbo.SmoothieIngredients
                WHERE   SmoothieId = @SmoothieId;

                EXECUTE (@Query);
            END
        ELSE 
            BEGIN

                IF @UserId = 0 
                    SET @UserId = NULL;

                INSERT  INTO dbo.Smoothie
                        ( Name, CreatedDate, Status, UserId )
                VALUES  ( N'', @CreatedDate, @Status, @UserId );

                SET @SmoothieId = SCOPE_IDENTITY();

                SET @Query = REPLACE(@Query, 'sId', @SmoothieId);
                EXECUTE (@Query);

            END 


        COMMIT TRAN

        SELECT @SmoothieId
        RETURN
    END TRY

    BEGIN CATCH
        ROLLBACK
    END CATCH

END
Run Code Online (Sandbox Code Playgroud)

或者您可以使用另一种数据库访问方法。