テンプレートでDynamicParametersを使用し、復帰パラメータをdapperで使用できますか?

.net c# dapper

質問

私が現在取り組んでいるシステムは、すべてのデータアクセスにストアドプロシージャを使用しています。私は現時点でDapperを探しています(これまでのところ素晴らしいです)が、テンプレートを使用して作成されたDynamicParametersオブジェクトを使用してパラメータの1つを出力パラメータにすることができるかどうかは疑問でした。例えば:

SP:

CREATE PROCEDURE InsertPerson
  @ID int Output,
  @Name varchar(100),
  @DOB DateTime2
AS
--INSERT STATEMENT

SET @ID = SCOPE_IDENTITY()

POCO:

internal class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public DateTime DOB { get; set; }
}

コード:

var procParams = new DynamicParameters(person);
connection.Execute("InsertPerson", procParams, commandType: CommandType.StoredProcedure);

// This is where i'm having the issue, can it be done?
person.ID = procParams.Get<int>("ID");

キーが見つからないため、現在のエラーが表示されます。格納されたprocsパラメータをすべて手動で設定せずにID出力パラメータを取得する方法はありますか?

受け入れられた回答

素早く調整することで、 Addはテンプレートの値を置き換え 、次のことを可能にします:

public void TestProcWithOutParameter()
{
    connection.Execute(
        @"CREATE PROCEDURE #TestProcWithOutParameter
@ID int output,
@Foo varchar(100),
@Bar int
AS
SET @ID = @Bar + LEN(@Foo)");
    var obj = new
    { // this could be a Person instance etc
        ID = 0,
        Foo = "abc",
        Bar = 4
    };
    var args = new DynamicParameters(obj);
    args.Add("ID", 0, direction: ParameterDirection.Output);
    connection.Execute("#TestProcWithOutParameter", args,
                 commandType: CommandType.StoredProcedure);
    args.Get<int>("ID").IsEqualTo(7);
}

それは十分に近いですか?既存の値または新しい値のParameterDirection.ReturnValue使用することもできます。オリジナルのテンプレートに直接更新されるわけではありませDynamicParametersインスタンスから値を取得する必要があります(図を参照)。


人気のある回答

DynamicParametersのコンストラクタを使用してテンプレートオブジェクトを指定する場合、 @IDが出力パラメータであることを指定する必要があります。まず、テンプレートを介して、 ParameterDirection.Inputに設定されます。これを追加すると、更新された値を持つようにオーバーライドされ、次のようにパラメータ名で値を取得できます。

procParams.Add("@ID", dbType: DbType.Int32, direction: ParameterDirection.Output);
// ... execute ...
person.ID = procParams.Get<int>("@ID");

私は上に示したことに加えて、これを働かせてクラスとコードを使用することができました。

編集:コメントで説明したように、ストアドプロシージャは宣言されたより多くの引数を受け入れません。したがって、別のアプローチでは、ストアドプロシージャを取り除き、インラインSQLに頼ることになります。クエリを使用すると、DapperはSQL文で指定されていないパラメータを無視します。これはこの問題に取り組むための回避策です:

string sql = "INSERT INTO Person (Name, DOB) VALUES (@Name, @DOB) SELECT SCOPE_IDENTITY()";
decimal id = conn.Query<decimal>(sql, procParams).First();
person.ID = (int)id;

SCOPE_IDENTITY()は整数ではなく小数点を返します。

理想的ではないもう一つのアイデアは、Dapperコードを修正し、 DynamicParametersクラスにRemoveメソッドを追加して不要なパラメータを削除することです。ストアドプロシージャを幸せにするために、すべてのパラメータを削除するように指定する時間を費やすので、これではあまり保存されません。これを実装することを決定した場合は、 parameters辞書から削除するキーを指定する際に大文字小文字が問題になることを覚えておいてparameters



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ