J'ai une procédure stockée dans ce format
CREATE PROCEDURE SP_MYTESTpROC
@VAR1 VARCHAR(10),
@VAR2 VARCHAR(20),
@BASEID INT ,
@NEWID INT OUTPUT
As Begin
INSERT INTO TABLE_NAME(username, firstname)
select @VAR1, @VAR2
WHERE ID = @BASEID
SET @NEWID = SCOPE_IDENTITY() AS INT
END
J'appelle cette procédure stockée à partir du code C # à l'aide de dapper. Ma question est: comment passer le paramètre de sortie à la procédure stockée lors de l'utilisation de dapper?
En recherchant simplement le fichier Test.cs , vous pouvez trouver cet exemple
public void TestProcSupport()
{
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);
connection.Execute(@"create proc #TestProc
@a int,
@b int output
as
begin
set @b = 999
select 1111
return @a
end");
connection.Query<int>("#TestProc", p, commandType: CommandType.StoredProcedure).First().IsEqualTo(1111);
p.Get<int>("c").IsEqualTo(11);
p.Get<int>("b").IsEqualTo(999);
}
Donc, je suppose que votre code C # pourrait être écrit comme
public void InsertData()
{
var p = new DynamicParameters();
p.Add("VAR1", "John");
p.Add("VAR2", "McEnroe");
p.Add("BASEID", 1);
p.Add("NEWID", dbType: DbType.Int32, direction: ParameterDirection.Output);
connection.Query<int>("SP_MYTESTpROC", p, commandType: CommandType.StoredProcedure);
int newID = p.Get<int>("NEWID");
}
En guise de remarque, n'utilisez pas SP comme préfixe pour votre procédure stockée. Il est réservé aux procédures définies par le système et vous pourriez vous retrouver en difficulté si Microsoft décide d'utiliser le même nom. Bien qu'improbable c'est une mauvaise pratique et pourquoi risquer?
Suite à la suggestion de "ath": Pour éviter la réflexion, DynamicParmers.AddDynamicParams () prend un objet anonyme, après quoi vous pouvez ajouter le paramètre de retour comme ceci ...
var param = new { A="a", B="b" };
var dynamicParameters = new DynamicParameters();
dynamicParameters.AddDynamicParams(parameters);
dynamicParameters.Add("return", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
utilisez maintenant l'objet dynamicParameters dans votre appel dapper au lieu de l'objet param anonyme.
(Vous pouvez également le faire pour un paramètre de sortie si vous préférez)
Si vous avez toujours un paramètre OUTPUT de type INTEGER nommé @id
(@id = @id OUTPUT
), vous pouvez créer une méthode d'extension comme celle-ci qui vous permettrait d'utiliser la syntaxe régulière Dapper
en passant la chaîne sql et un objet anonymous
:
using Dapper;
using System.Data;
using System.Data.SqlClient;
public static int ExecuteOutputParam
(this IDbConnection conn, string sql, object args)
{
// Stored procedures with output parameter require
// dynamic params. This assumes the OUTPUT parameter in the
// SQL is an INTEGER named @id.
var p = new DynamicParameters();
p.Add("id", dbType: DbType.Int32, direction: ParameterDirection.Output);
var properties = args.GetType().GetProperties();
foreach (var prop in properties)
{
var key = prop.Name;
var value = prop.GetValue(args);
p.Add(key, value);
}
conn.Execute(sql, p);
int id = p.Get<int>("id");
return id;
}
Cela utilise la réflexion pour lire toutes les propriétés, mais si vous pouvez prendre cette pénalité, vous n'avez pas à chauffer le DynamicParameters
pour chaque appel.
Pour les transactions, faites une méthode d'extension sur SqlTransaction
en la passant à Execute comme ceci:
transaction.Connection.Execute(sql, p, transaction);