将 Dapper 与 Oracle 结合使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6212992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Dapper with Oracle
提问by Wolfwyrd
We use Oracle as our database provider and have looked into replacing some of our data access layer (hard to maintain, harder to merge XSD's) with a saner repository based pattern using Dapper at the bottom layer. However, we have hit a number of issues when using it with oracle.
我们使用 Oracle 作为我们的数据库提供者,并考虑将我们的一些数据访问层(难以维护,更难合并 XSD)替换为在底层使用 Dapper 的更合理的基于存储库的模式。但是,在将其与 oracle 一起使用时,我们遇到了许多问题。
Named Parameters: these seem to be ignored, whenever they are used in a query Oracle seems to interpret them in any order it fancies. The SqlMapper returns correctly named parameters, they just aren't interpreted correctly in Oracle
The "@" naming convention for variables is incompatible with oracle named parameters. It expects to see ":" in front of any parameters
命名参数:这些似乎被忽略了,无论何时在查询中使用它们时,Oracle 似乎都以它喜欢的任何顺序解释它们。SqlMapper 返回正确命名的参数,它们只是在 Oracle 中没有被正确解释
变量的“@”命名约定与 oracle 命名参数不兼容。它期望在任何参数前看到“:”
Has anybody previously encountered this and have any workarounds?
有没有人以前遇到过这个问题并有任何解决方法?
回答by Marc Gravell
IMO, the correct approach here is notto (as per the accepted answer) use the database specific parameter prefix (so @
for sql-server, :
for oracle) - but rather: use no prefix at all. So ultimately this is:
IMO,这里的正确的做法是不以(按照公认的答案)使用数据库特定的参数前缀(这样@
的SQL服务器,:
用于Oracle) -而是:使用无前缀可言。所以最终这是:
il.Emit(OpCodes.Ldstr, prop.Name);
(etc)
(等等)
In particular, a static
property would be bad as it would limit you to one vendor per AppDomain
.
特别是,一个static
属性会很糟糕,因为它会限制您每个AppDomain
.
Dapper has been updated with this change. It also now dynamically detects BindByName
and sets it accordingly (all without needing a reference to OracleCommand
).
Dapper 已更新此更改。它现在还可以动态检测BindByName
并相应地设置它(所有这些都不需要对 的引用OracleCommand
)。
回答by Wolfwyrd
Resolution of the named parameter issue turned out to be because Oracle commands require the BindByName property set to true. To resolve this required a tweak to the SqlMapper itself. This is a bit nasty as the tweak isnt portable (it relies on a type check for a specific Oracle Command) but it works for our needs for the moment. The change involves updating the SetupCommand method, after creating the command form the connection object we type check and set the flag like so (~ln 635):
命名参数问题的解决结果是因为 Oracle 命令需要将 BindByName 属性设置为 true。要解决此问题,需要对 SqlMapper 本身进行调整。这有点令人讨厌,因为该调整不可移植(它依赖于对特定 Oracle 命令的类型检查),但它目前可以满足我们的需求。更改涉及更新 SetupCommand 方法,在从连接对象创建命令后,我们键入检查并设置标志,如下所示(~ln 635):
var cmd = cnn.CreateCommand();
if (cmd is OracleCommand)
{
((OracleCommand)cmd).BindByName = true; // Oracle Command Only
}
Finally to address the issue of the "@" to ":" problem in parameter names involved altering the CreateParamInfoGenerator method. I added a static string - DefaultParameterCharacter setting its value to ":" then modified ln 530 from:
最后解决参数名称中“@”到“:”的问题,涉及更改 CreateParamInfoGenerator 方法。我添加了一个静态字符串 - DefaultParameterCharacter 将其值设置为“:”,然后从以下位置修改 ln 530:
il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [c
to
到
il.Emit(OpCodes.Ldstr, DefaultParameterCharacter + prop.Name); // stack is now [parameters] [command] [name] (Changed @ to : for oracle)
and ln 546 from:
和 ln 546 来自:
il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] (Changed @ to : for oracle)
to:
到:
il.Emit(OpCodes.Ldstr, DefaultParameterCharacter + prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] (Changed @ to : for oracle)
This made dapper work flawlessly with Oracle commands
这使得 dapper 可以完美地使用 Oracle 命令