web-dev-qa-db-fra.com

Comment utiliser Dapper pour obtenir la valeur de retour du proc stocké?

J'utilise Dapper dans le projet asp.net mvc 4 .net f/w 4.6.1 en utilisant SQL Server 2016 Express

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

J'ai un proc stocké qui supprime de 2 tables qui devraient être transactionnelles

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

Ma méthode de repo utilise un dapper comme celui-ci

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");
        }

Le returnValue j'obtiens 1 à chaque fois, ce qui est compréhensible puisque dapper retourne le nombre de lignes affectées.

Cependant, je veux obtenir la valeur de l'instruction de retour de mon proc stocké pour vérifier les erreurs lors de la suppression transactionnelle (qui dans mon cas est 0 pour le succès et 1 pour toute erreur)

Comment puis-je y parvenir?

Avec le métal nu ado.net, je faisais ça et ça a marché

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

Avec dapper, j'ai essayé con.ExecuteScalar qui ne fonctionne pas car les métadonnées dapper révèlent que scalar // Renvoie: // La première cellule sélectionnée

Toute aide serait appréciée?

Voici la prochaine procédure que je dois exécuter avec 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
8
Hamza Ahmed Zia

Vous pouvez déclarer des paramètres dynamiques avec direction: ReturnValue Vous pouvez également utiliser "select" au lieu de "return" et utiliser Query<T> extension.

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));
    }
}
17
Void Ray

vous devrez définir un SqlParameter pour votre procédure stockée avec un Direction.ReturnValue

0
NIts577