在c#代码中使用dapper传递输出参数给存储过程
本文关键字:输出 参数 存储过程 dapper 代码 | 更新日期: 2023-09-27 17:49:48
我有一个这样格式的存储过程
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
我正在使用dapper从c#代码调用这个存储过程。我的问题是:如何在使用dapper时将输出参数传递给存储过程?
只要搜索Test.cs文件,就可以找到这个示例
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);
}
所以,我认为你的c#代码可以写成
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");
}
作为旁注,不要使用SP作为存储过程的前缀。它是为系统定义的过程保留的,如果微软决定使用相同的名称,您可能会发现自己陷入麻烦。尽管不太可能,但这是一种不好的做法,为什么要冒险呢?
到"ath' "建议:为了避免反射,DynamicParmers.AddDynamicParams()接受一个匿名对象,之后你可以像这样添加返回参数…
var param = new { A="a", B="b" };
var dynamicParameters = new DynamicParameters();
dynamicParameters.AddDynamicParams(param);
dynamicParameters.Add("return", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
现在在你的dapper调用中使用dynamicParameters对象而不是匿名param对象。
(如果您愿意,也可以对输出参数这样做)
如果您总是有一个名为@id
(@id = @id OUTPUT
)的INTEGER类型的OUTPUT参数,您可以创建这样的扩展方法,这将允许您使用常规的Dapper
语法传递sql字符串和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;
}
这使用反射来读取所有属性,但是如果你可以接受这种惩罚,你就不必为每个调用都样板化DynamicParameters
。
对于事务,在SqlTransaction
上创建一个扩展方法,传递给Execute,如下所示:
transaction.Connection.Execute(sql, p, transaction);