简体   繁体   English

将 Dapper 与 Oracle 一起使用

[英]Using Dapper with Oracle

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.我们使用 Oracle 作为我们的数据库提供者,并且已经考虑用底层使用 Dapper 的基于存储库的更合理的模式替换我们的一些数据访问层(难以维护,更难合并 XSD)。 However, we have hit a number of issues when using it with oracle.但是,在将它与 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.命名参数:这些似乎被忽略,无论何时在查询中使用它们 Oracle 似乎以它喜欢的任何顺序解释它们。 The SqlMapper returns correctly named parameters, they just aren't interpreted correctly in Oracle SqlMapper 返回正确命名的参数,只是在 Oracle 中没有正确解释它们

  • The "@" naming convention for variables is incompatible with oracle named parameters.变量的“@”命名约定与 oracle 命名参数不兼容。 It expects to see ":" in front of any parameters它希望在任何参数前面看到“:”

Has anybody previously encountered this and have any workarounds?有没有人以前遇到过这种情况并有任何解决方法?

IMO, the correct approach here is not to (as per the accepted answer) use the database specific parameter prefix (so @ for sql-server, : for oracle) - but rather: use no prefix at all . IMO,这里的正确方法不是(根据接受的答案)使用数据库特定的参数前缀(所以@代表 sql-server, :代表 oracle) - 而是:根本不使用前缀。 So ultimately this is:所以最终这是:

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

(etc) (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. Dapper 已根据此更改进行了更新。 It also now dynamically detects BindByName and sets it accordingly (all without needing a reference to OracleCommand ).它现在还动态检测BindByName并相应地设置它(所有这些都不需要对OracleCommand的引用)。

Resolution of the named parameter issue turned out to be because Oracle commands require the BindByName property set to true.命名参数问题的解决原来是因为 Oracle 命令需要将 BindByName 属性设置为 true。 To resolve this required a tweak to the SqlMapper itself.要解决这个问题,需要对 SqlMapper 本身进行调整。 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.这有点讨厌,因为调整不是可移植的(它依赖于特定 Oracle 命令的类型检查),但它目前可以满足我们的需求。 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):更改涉及更新 SetupCommand 方法,在从连接 object 创建命令后,我们键入检查并设置标志,如下所示(~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.最后,要解决参数名称中“@”到“:”的问题,涉及更改 CreateParamInfoGenerator 方法。 I added a static string - DefaultParameterCharacter setting its value to ":" then modified ln 530 from:我添加了一个 static 字符串 - 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 命令

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM