將Dapper與Oracle結合使用

c# dapper oracle

我們使用Oracle作為我們的數據庫提供者,並且已經考慮使用底層的Dapper替換我們的一些數據訪問層(難以維護,難以合併XSD)和基於存儲庫的模式。但是,在與oracle一起使用時,我們遇到了許多問題。

  • 命名參數:這些似乎被忽略,無論何時在查詢中使用它,Oracle似乎都會以它所想的任何順序來解釋它們。 SqlMapper返回正確命名的參數,它們在Oracle中無法正確解釋

  • 變量的“@”命名約定與oracle命名參數不兼容。它希望在任何參數前面看到“:”

有沒有人以前遇到這個並有任何解決方法?

一般承認的答案

IMO,這裡的正確的做法是不是 (按公認的答案)使用數據庫特定的參數前綴(所以@為SQL服務器, :用於Oracle) -而是: 在所有使用沒有前綴。所以最終這是:

il.Emit(OpCodes.Ldstr, prop.Name);

(等等)

特別是, static屬性會很糟糕,因為它會限制每個AppDomain一個供應商。

Dapper已更新此更改。它現在還動態檢測BindByName並相應地設置它(所有這些都不需要引用OracleCommand )。


熱門答案

已解決命名參數問題的原因是Oracle命令要求將BindByName屬性設置為true。要解決此問題,需要對SqlMapper本身進行調整。由於調整不是可移植的(它依賴於特定Oracle命令的類型檢查),這有點令人討厭,但它現在可以滿足我們的需求。更改涉及更新SetupCommand方法,在創建命令後,我們鍵入的連接對象檢查並設置標誌,如此(~ln 635):

var cmd = cnn.CreateCommand();
if (cmd is OracleCommand)
{
    ((OracleCommand)cmd).BindByName = true; // Oracle Command Only
}

最後解決參數名稱中“@”到“:”問題涉及改變CreateParamInfoGenerator方法的問題。我添加了一個靜態字符串 - DefaultParameterCharacter將其值設置為“:”然後從以下位置修改ln 530:

il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [c

il.Emit(OpCodes.Ldstr, DefaultParameterCharacter + prop.Name); // stack is now [parameters] [command] [name] (Changed @ to : for oracle)

和來自:

il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] (Changed @ to : for oracle)

至:

il.Emit(OpCodes.Ldstr, DefaultParameterCharacter + prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] (Changed @ to : for oracle)

這使得dapper與Oracle命令完美配合



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