将 Dapper 与 Oracle 结合使用

发布于 2024-11-13 22:48:45 字数 335 浏览 4 评论 0原文

我们使用 Oracle 作为我们的数据库提供商,并考虑用底层使用 Dapper 的更健全的基于存储库的模式来替换我们的一些数据访问层(难以维护,更难合并 XSD)。然而,我们在将其与 Oracle 一起使用时遇到了许多问题。

  • 命名参数:每当在查询中使用这些参数时,这些参数似乎都会被忽略,Oracle 似乎会按照它喜欢的任何顺序解释它们。 SqlMapper 返回正确命名的参数,只是在 Oracle 中没有正确解释它们

  • 变量的“@”命名约定与 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. However, we have hit a number of issues when using it with 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

Has anybody previously encountered this and have any workarounds?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

咋地 2024-11-20 22:48:45

IMO,这里正确的方法是(根据接受的答案)使用数据库特定的参数前缀(因此sql-server的@: 对于 oracle) - 而是:根本不使用前缀。所以最终是:(

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

等等)

特别是,static 属性会很糟糕,因为它会限制每个 AppDomain 只能有一个供应商。

Dapper 已根据此更改进行了更新。现在,它还可以动态检测 BindByName 并进行相应设置(所有这些都不需要引用 OracleCommand)。

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. So ultimately this is:

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.

Dapper has been updated with this change. It also now dynamically detects BindByName and sets it accordingly (all without needing a reference to OracleCommand).

素染倾城色 2024-11-20 22:48:45

命名参数问题的解决结果是因为 Oracle 命令要求 BindByName 属性设置为 true。要解决这个问题,需要对 SqlMapper 本身进行调整。这有点令人讨厌,因为调整不可移植(它依赖于特定 Oracle 命令的类型检查),但它目前可以满足我们的需求。更改涉及更新 SetupCommand 方法,在从连接对象创建命令后,我们键入 check 并设置标志,如下所示 (~ln 635):

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

最后解决所涉及参数名称中的“@”到“:”问题更改 CreateParamInfoGenerator 方法。我添加了一个静态字符串 - DefaultParameterCharacter 将其值设置为“:”,然后修改了 ln 530 from:

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)

和 ln 546 from:

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)

这使得 dapper 可以完美地与 Oracle 命令一起工作

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):

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:

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:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文