¿Cómo uso Dapper para obtener el valor de retorno del proceso almacenado?

asp.net-mvc c# dapper data-access-layer sql-server

Pregunta

Estoy usando Dapper en asp.net mvc 4 project .net f / w 4.6.1 usando sql server 2016 express

<packages>
  <package id="Dapper" version="1.50.2" targetFramework="net461" />
</packages> 

Tengo un proceso almacenado que elimina de 2 tablas que deberían ser transaccionales

ALTER PROCEDURE [dbo].[FeedbackDelete] @FeedbackID UNIQUEIDENTIFIER
AS 
    SET NOCOUNT OFF 
    SET XACT_ABORT ON  

BEGIN TRANSACTION
    DELETE
    FROM dbo.Document
    WHERE FeedbackId = @FeedbackID
    IF(@@ERROR != 0)
        BEGIN
            ROLLBACK TRANSACTION
            RETURN 1
        END

    DELETE
    FROM   [dbo].[Feedback]
    WHERE  [FeedbackID] = @FeedbackID
    IF(@@ERROR != 0 OR @@ROWCOUNT != 1)
        BEGIN
            ROLLBACK TRANSACTION
            RETURN 1
        END

COMMIT TRANSACTION
RETURN 0

Mi método repo usa dapper como este

public Response DeleteFeedback(Guid feedbackId)
        {
            string storedProcName = "FeedbackDelete";
            int returnValue = int.MinValue;
            using (var con = Connection)
            {
                con.Open();
                returnValue = con.Execute(storedProcName, new { feedbackId }, commandType: CommandType.StoredProcedure);
            }
            return Convert.ToInt32(returnValue) == 0 ? new Response(Code.Success, "Feedback successfully deleted") : new Response(Code.Failure, "There was an error deleting feedback");
        }

El returnValue que obtengo es 1 cada vez, lo que es comprensible ya que dapper devuelve el número de filas afectadas.

Sin embargo, quiero llegar al valor de la declaración de devolución de mi proceso almacenado para verificar errores durante la eliminación transaccional (que en mi caso es 0 para el éxito y 1 para cualquier error)

¿Cómo logro esto?

Con bare.net ado.net solía hacer esto y funcionó

var returnValue = db.ExecuteScalar(storedProcName, new object[] { feedbackId });

Con dapper, he intentado con.ExecuteScalar, que no funciona, ya que los metadatos dapper revelan que escalar // Devuelve: // La primera celda seleccionada

Cualquier ayuda será apreciada?

Este es el siguiente procedimiento que necesito ejecutar con Dapper

ALTER PROCEDURE [dbo].[FeedbackUpdate] 
    @DocumentData VARBINARY(MAX),
    @DocumentName NVARCHAR(100),
    @FeedbackID UNIQUEIDENTIFIER,
    @FirstName NVARCHAR(100),
    @LastName NVARCHAR(100),
    @Notes NVARCHAR(MAX)
AS 
    SET NOCOUNT ON 
    SET XACT_ABORT ON  

    BEGIN TRAN

    UPDATE [dbo].[Feedback]
    SET    [FirstName] = @FirstName, [LastName] = @LastName, [Notes] = @Notes
    WHERE  [FeedbackID] = @FeedbackID
    IF(@@ERROR != 0 OR @@ROWCOUNT != 1)
        BEGIN
            ROLLBACK TRAN
            RETURN 1
        END

    IF DATALENGTH(@DocumentData) > 1
    BEGIN

            DELETE
            FROM   [dbo].[Document]
            WHERE  FeedbackId = @FeedbackId
            IF(@@ERROR != 0)
                BEGIN
                    ROLLBACK TRAN
                    RETURN 1
                END

            INSERT [dbo].[Document] (DocumentData,DocumentName,DocumentId,FeedbackId)
            VALUES(@DocumentData,@DocumentName,NEWID(),@FeedbackID)
            IF(@@ERROR != 0 OR @@ROWCOUNT != 1)
                BEGIN
                    ROLLBACK TRAN
                    RETURN 1
                END
        END

        COMMIT TRAN
        RETURN 0

Respuesta aceptada

Puede declarar parámetros dinámicos con la dirección: ReturnValue También puede usar "seleccionar" en lugar de "devolver" y usar la extensión Query<T> .

create procedure sp_foo
    as
    begin
        return 99
    end

[Test]
public void TestStoredProcedure()
{
    using (var conn = new SqlConnection(@"Data Source=.\sqlexpress;Integrated Security=true; Initial Catalog=foo"))
    {
        var p = new DynamicParameters();
        p.Add("@foo", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

        conn.Execute("sp_foo", p, commandType: CommandType.StoredProcedure);

        var b = p.Get<int>("@foo");

        Assert.That(b, Is.EqualTo(99));
    }
}

Respuesta popular

tendrás que definir un parámetro SqlParameter para tu procedimiento almacenado con un Direction.ReturnValue



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué