2012-09-09 5 views
7

aquí está mi procedimiento almacenado. cuando lo pruebo, siempre obtengo el resultado correcto.Usando Dapper.net para llamar al procedimiento almacenado, siempre devuelve -1 de vuelta

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 

Sin embargo, cuando llamo a este procedimiento almacenado con dapper.net, siempre devuelve -1 de nuevo.

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

Probablemente, dapper.net no puede recoger el valor de retorno del procedimiento almacenado. pero realmente no sé cómo arreglarlo. por favor ayuda.

Respuesta

2

Parece que Dapper.net usa SqlCommand.ExecuteNonQuery para el método Execute. Esto devuelve el número de filas afectadas, no el valor de la declaración de devolución. Lo que estás buscando es Query

return connection.Query<int>("AddSmoothieIngredients", parameter, commandType: CommandType.StoredProcedure).First(); 

Aunque no creo que va a captar la instrucción de retorno o bien, en cuyo caso tendrá que modificar el procedimiento almacenado para devolver un conjunto de resultados.

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 

O podría utilizar otro método de acceso a la base de datos.

+0

gracias. pero todavía tiene que usar execute, encontré otra muestra en línea y funciona. – qinking126

13

Encontré la solución, aquí está el código de muestra que encontré en línea. y funciona.

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

Así que la razón por la que Ejecutar() devuelve -1 se debe a su sproc tiene SET NOCOUNT ON; la que "suprime el '' mensaje después de cualquier LMD" xx filas afectadas de acuerdo con this question. Ya sea que quiera deshabilitar eso o no, también se discute otra cuestión en ese enlace.

Me encontré con el mismo problema, así que pensé en tirar mis 2 centavos.

+0

¡Nunca lo sabía! +1 – nawfal

1

Recientemente tuve que cambiar un procedimiento existente para, además, devolver un valor, y había estado usando un tipo anónimo para pasar los parámetros. En este contexto, lo realmente agradable es que DynamicParameters admite un tipo anónimo como parámetro de entrada, lo que hace que este cambio sea fácil de implementar.

que tenía los siguientes:

cnn.Execute("spMagicProc", new { a = 11, x = 13, y = 14, z = "something" }, 
    commandType: commandType.StoredProcedure); 

yo era capaz de cambiar eso para:

var p = new DynamicParameters(new { a = 11, x = 13, y = 14, z = "something" }); 
p.Add("@rval", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue); 

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

int rval = p.Get<int>("@rval"); 
Cuestiones relacionadas