この形式のストアドプロシージャがあります
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's」の提案に加えて:リフレクションを回避するために、DynamicParmers.AddDynamicParams()は匿名オブジェクトを取得します。その後、次のような戻りパラメーターを追加できます。
var param = new { A="a", B="b" };
var dynamicParameters = new DynamicParameters();
dynamicParameters.AddDynamicParams(parameters);
dynamicParameters.Add("return", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
匿名のparamオブジェクトの代わりに、dapper呼び出しでdynamicParametersオブジェクトを使用するようになりました。
(必要に応じて、出力パラメーターに対してこれを行うこともできます)
常に@id
(@id = @id OUTPUT
)という名前のINTEGER型のOUTPUTパラメーターがある場合、sqlを渡す通常のDapper
構文を使用できるこのような拡張メソッドを作成できます。文字列と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);