2017-05-24 5 views
1

J'utilise Dapper dans asp.net mvc 4 projet .net f/w 4.6.1 utilisant le serveur SQL 2016 expressComment utiliser Dapper pour obtenir la valeur de retour du proc stocké?

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

j'ai une procédure stockée qui supprime de 2 tables qui devrait être transactionnel

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 repo utilise pimpant 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 je reçois est 1 chaque fois wh Cela est compréhensible puisque dapper renvoie le nombre de lignes affectées.

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

Comment puis-je obtenir ce?

Avec ado.net en métal nu j'utilisé pour le faire et cela a fonctionné

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

Avec pimpant j'ai essayé con.ExecuteScalar qui ne fonctionne pas depuis métadonnées pimpant révèle que scalaire // Retourne: // La première cellule sélectionnée

Toute aide sera appréciée?

Voici la procédure suivante 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 
+1

Ceci est complètement hors sujet, mais vous permettra d'économiser des maux de tête. La plupart du temps, votre requête sera beaucoup plus rapide si vous définissez des variables locales, les définissez sur vos paramètres d'entrée et utilisez vos variables locales dans votre requête. J'ai obtenu une performance 10x facile de la plupart des SPROC en faisant cette seule chose. Désolé pour la distraction, mais vous me remercierez plus tard. – SteveJ

+1

https://stackoverflow.com/questions/14247081/return-values-from-dapper-net-query-with-stored-procedure – SteveJ

+0

@SteveJ Merci pour votre conseil intéressant. Toute explication sur les raisons pour lesquelles les performances augmentent avant que je n'en parle avec mon équipe et ne mette à jour les procédures stockées. J'aurais besoin d'un cas rationnel fort pour le bouleversement ;-) –

Répondre

5

Vous pouvez déclarer params dynamique avec la direction: ReturnValue Vous pouvez également utiliser "select" au lieu de "return" et utiliser l'extension 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)); 
    } 
} 
+0

J'ai utilisé select dans mes procédures stockées et Query . Je ne voulais pas utiliser DynamicParameters puisque j'utilise la réflexion pour ajouter des paramètres aux procs stockés –

1

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