2013-05-28 57 views
3

我試着用Dapper與Oracle,我試圖運行一個多結果集查詢,但Oracle需要一個refcursor dbtype。Dapper與甲骨文傳入DbParameter

StringBuilder query = new StringBuilder("BEGIN "); 
query.Append("OPEN :rs1 FOR SELECT * FROM Table1 where key=:KEY; "); 
query.Append("OPEN :rs2 FOR SELECT * FROM Table2 where key=:KEY; "); 
query.Append("END;"); 
  • 有沒有辦法通過一個的OracleParameter(也許爲的DbParameter?),以短小精悍的?當我嘗試時,它拋出一個錯誤。

  • 使用DynamicParameter與使用DbParameter(假設類型已知等)有什麼優勢?

回答

4
  1. 在最近一次生成,允許在參數更多的控制增加了一個新的接口 - 它被添加到支持SQL服務器的臺灣居民入境許可證,但應在這種情況下工作。不過,我也很滿意爲任何看起來像dbparameter的類型添加特殊外殼 - 並直接添加它們,這將允許您直接添加一個oracle參數。

  2. DynamicParameters約爲有多少參數添加,所以它是有點正交於值vs DbParameter的討論。目前,代碼通常更喜歡自己控制添加參數,因此調用者只知道「一個名爲id的int值爲7」 - 而不是任何ado.net的細節。但它可以做到。


編輯:如果你真的要使用列表-的參數(即List<DbParameter>等),那麼你就可以做到這一點的東西,如:

public class DbParams : Dapper.SqlMapper.IDynamicParameters, 
         IEnumerable<IDbDataParameter> 
{ 
    private readonly List<IDbDataParameter> parameters = 
     new List<IDbDataParameter>(); 
    public IEnumerator<IDbDataParameter> GetEnumerator() { 
     return parameters.GetEnumerator(); } 
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } 
    public void Add(IDbDataParameter value) 
    { 
     parameters.Add(value); 
    } 
    void Dapper.SqlMapper.IDynamicParameters.AddParameters(IDbCommand command, 
     Dapper.SqlMapper.Identity identity) 
    { 
     foreach (IDbDataParameter parameter in parameters) 
      command.Parameters.Add(parameter); 
    } 
} 

與用法如:

public void TestCustomParameters() 
{ 
    var args = new DbParams { 
     new SqlParameter("foo", 123), 
     new SqlParameter("bar", "abc") 
    }; 
    var result = connection.Query("select [email protected], [email protected]", args).Single(); 
    int foo = result.Foo; 
    string bar = result.Bar; 
    foo.IsEqualTo(123); 
    bar.IsEqualTo("abc"); 
} 

它通過了測試。

但是,我必須強調,我寧願不妨礙使用DB-參數的知識,除非它真的真的需要知道調用代碼;我會通過遠喜歡:

var args = new { 
    foo = 123, bar = "abc" 
}; 

這不正是同樣的事情,但沒有下降到ADO.NET;如果您使用「修飾」的ADO.NET連接(例如,mini-profiler),這可能尤其重要 - 在這種情況下,您獲得的圖層是而不是OracleCommand/OracleConnection等 - 它被抽象化。這意味着強制添加OracleParameter可能並不總是工作 - 但添加名稱"foo"和值123的參數 - 這是非常可靠的。

+1

謝謝你的回覆。我認爲整個班級添加參數是過度的。我迅速追蹤了代碼,這看起來有竅門(在GetCacheInfo中)。我認爲它保持了代碼的精神,讓我知道如果你看到一個問題: 'if(identity.parametersType == typeof(List )) \t \t \t \t \t { \t \t \t \t \t \t info.ParamReader =(CMD,OBJ)=> \t \t \t \t \t \t { \t \t \t \t \t \t \t列表 collection =(List )obj; \t \t \t \t \t \t \t的foreach(在收集System.Data.Common.DbParameter P) \t \t \t \t \t \t \t { \t \t \t \t \t \t \t \t cmd.Parameters.Add(P); \t \t \t \t \t \t \t} \t \t \t \t \t \t}; \t \t \t \t \t}' – user2429012

+0

@ user2429012一個 「全班」 可以被看作是矯枉過正,但我​​的觀點是:爲什麼不只是一個匿名類型:'新{ID = 123,名稱= 「ABC」}' ?特別是其中的一個關鍵部分是現在的調用者不需要**來擔心數據庫特定的功能,除非他們需要時發生非常罕見的事件。然而!如果你真的想要ADO.NET參數列表(我認爲這是一個壞主意,說實話) - 請參閱上面的編輯,它沒有任何改變。 –