我可以將DynamicParameters與Template一起使用並在dapper中使用返回參數嗎?

.net c# dapper

我目前正在處理的系統使用存儲過程進行所有數據訪問。我現在正在研究Dapper(到目前為止它看起來很棒)但是我想知道我是否可以使用使用模板創建的DynamicParameters對象,但是將其中一個參數作為輸出參數。例如:

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");

當前我收到錯誤,因為找不到密鑰。有沒有辦法獲得ID輸出參數而無需手動設置所有存儲的procs參數?

一般承認的答案

通過快速調整, Add now 將替換模板中的值,允許:

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()返回小數,而不是int。

另一個我認為不理想的想法是修改Dapper代碼並向DynamicParameters類添加Remove方法以刪除不需要的參數。這並不會為您節省太多,因為您仍然會花時間指定要刪除所有參數以使存儲過程滿意。如果您決定實現這一點,請記住在指定要從parameters字典中刪除的鍵時該情況很重要。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因