Manera alternativa de obtener el parámetro de salida del procedimiento almacenado

dapper

Pregunta

Me encanta usar Dapper para mis necesidades de ORM, pero sé que debe haber una mejor manera de insertar / actualizar mi base de datos del servidor SQL utilizando un procedimiento almacenado y listas fuertemente tipadas.

Por ejemplo:

Tengo una canción de clase:

    public class Song
{
    public int Id { get; set; }
    public string title { get; set; }
    public string genre { get; set; }
}

y alguien envía una lista de canciones:

 List<Song> songs = new List<Song> { 
            new Song { Id = 1, title = "Song 1" , genre="rock"}, 
            new Song { Id = 2, title = "Song 2" , genre="disco"}};

Quiero actualizar la base de datos usando mi procedimiento almacenado que inserta la nueva canción o la actualiza si la canción ya existe. Mi procedimiento almacenado tiene dos parámetros de salida: @success_added int = 0 and @success_updated int = 0

mi sproc es el siguiente:

ALTER PROCEDURE [dbo].[UpdateSong] 
@Id int = 0, 
@title varchar(25) = NULL,
@genre varchar(25) = NULL,
@success_updated bit = 0 OUTPUT,
@success_added bit = 0 OUTPUT
AS
IF NOT EXISTS (SELECT Id  FROM Songs WHERE Id = @Id)
    BEGIN
        INSERT INTO Songs
        (
        -- Id created by db
        title,
        genre
        ) 
        VALUES
        (
        @title, 
        @genre
        )
        SELECT @Success_Added = 1, @Success_Updated = 0
    END
ELSE -- song already exists
    BEGIN
        UPDATE Songs  
        SET
        title = @title,
        @genre = @genre
        WHERE Id = @Id
        SELECT @Success_Added = 0, @Success_Updated = 1
    END
RETURN

Sé que esto funciona:

dbConn.Open();
DynamicParameters p = new DynamicParameters();
foreach (var song in songs)
  {
    p.Add("@Id", song.Id);
    p.Add("@title", song.title);
    p.Add("@genre", song.genre);
    p.Add("@success_updated", dbType: DbType.Boolean, direction: ParameterDirection.Output);
    p.Add("@success_added", dbType: DbType.Boolean, direction: ParameterDirection.Output);
    dbConn.Execute("Test_UpdateSong", p, commandType: CommandType.StoredProcedure);
    Console.WriteLine("@success_added: " + p.Get<Boolean>("@success_added"));
    Console.WriteLine("@success_updated: " + p.Get<Boolean>("@success_updated"));
  }
dbConn.Close();

Pero eso requiere convertir manualmente cada propiedad de la canción a un tipo anónimo DynamicParameter. Prefiero simplemente hacer esto:

dbConn.Open();
foreach (var song in songs)
  {
    var updateResult = dbConn.Query<dynamic>("Test_UpdateSong", song, commandType: CommandType.StoredProcedure);
  }
dbConn.Close();

Lo cual también funciona. Pero, ahora, ¿cómo obtengo mis parámetros de salida?

Respuesta aceptada

Como dije originalmente, no quería tener que convertir manualmente cada propiedad de clase a un parámetro dinámico de Dapper. Esto es crítico porque si creo un método genérico, es posible que no sepa qué clase se pasa al método y, por lo tanto, qué propiedades pasar para convertir a parámetros dinámicos. Tomando el consejo de @Metro Smurfs (cuando todo lo demás falla, lea las instrucciones), busqué en la clase de prueba de Dapper y encontré una solución que funciona para mí:

DynamicParameters p = new DynamicParameters(song);

añadiendo el objeto de la canción al constructor DynamicParameters, se crea una plantilla DynamicParameters que convertirá automáticamente todas las propiedades en parámetros. Entonces simplemente puedo agregar mis dos parámetros de salida y ejecutar el sproc:

p.Add("@success_updated", dbType: DbType.Boolean, direction: ParameterDirection.Output);
p.Add("@success_added", dbType: DbType.Boolean, direction: ParameterDirection.Output);
dbConn.Execute("Test_UpdateSong", p, commandType: CommandType.StoredProcedure);
// get my output parameters...
var success_added = p.Get<bool>("@success_Added");
var success_added = p.Get<bool>("@success_Updated");

¡y estoy listo para ir! Gracias a @Nick y @Metro Smurf por las sugerencias!



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é