将 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 23:52:06  来源:igfitidea点击:

Using Dapper with Oracle

c#oracledapper

提问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 staticproperty 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 BindByNameand 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 命令