c# - Dapper 参数不起作用

标签 c# dapper

我正在尝试通过以下简单查询使用 Dapper orm:

var sqlString = new StringBuilder();
sqlString.Append("select a.acct AccountNumber,");
sqlString.Append("       b.first_name FirstName,");
sqlString.Append("       b.last_name LastName,");
sqlString.Append("       a.rr RrNumber,");
sqlString.Append("       c.addr1 AddressLine1,");
sqlString.Append("       c.addr2 AddressLine2,");
sqlString.Append("       c.addr3 AddressLine3,");
sqlString.Append("       c.addr4 AddressLine4,");
sqlString.Append("       c.addr5 AddressLine5,");
sqlString.Append("       c.addr6 AddressLine6,");
sqlString.Append("       c.addr7 AddressLine7,");
sqlString.Append("       c.addr8 AddressLine8 ");
sqlString.Append("from (pub.mfclac as a left join pub.mfcl as b on a.client=b.client) ");
sqlString.Append("left join pub.mfclad as c on a.client=c.client ");
sqlString.Append("where a.acct = '@ZYX'");

var connection = new OdbcConnection(_connectionString);

var result = connection.Query(sqlString.ToString(),
    new
    {
        ZYX = accountNumber
    });            

但是,当我使用已知存在的 accountNumber 执行此操作时,dapper 不返回任何内容。因此,我尝试删除引号以验证参数实际上已被帐号替换,但是从服务器返回的错误表明“@ZYX”周围存在语法错误。这意味着 dapper 不会用它的给定值替换参数。任何想法为什么会这样?从现有的有限文档来看,这应该“正常工作”。


编辑1

无法让它工作。使用 string.format 插入参数作为解决方法。

最佳答案

这里有两个问题;首先(尽管您在问题中注意到这一点)where a.acct = '@ZYX',在 SQL 规则下,不使用任何参数 - 它看起来与恰好包含的文字字符串相匹配@ 符号。对于 SQL-Server(请参阅下面的注释),正确的用法是 where a.acct = @ZYX

但是!由于您使用的是 OdbcConnection,命名参数不适用。如果您实际上连接到 SQL-Server 之类的东西,我强烈建议您使用纯 ADO.NET 客户端,它具有比 ODBC 更好的特性和性能。但是,如果 ODBC 是您唯一的选择:它不使用命名参数。直到几天前,这才是一个主要问题,但根据 Passing query parameters in Dapper using OleDb ,代码(但还不是 NuGet 包)现在支持 ODBC。如果您从源代码构建(或等待下一个版本),您应该能够使用:

...
where a.acct = ?

在你的命令中,并且:

var result = connection.Query(sqlString.ToString(),
new {
    anythingYouLike = accountNumber
});

请注意,ODBC 不使用名称 (anythingYouLike),因此可以是...任何您喜欢的名称。在更复杂的场景中,例如:

.Execute(sql, new { id = 123, name = "abc", when = DateTime.Now });

dapper 使用一些关于如何实现匿名类型的知识来理解值的原始顺序,以便它们以正确的顺序添加到命令中(idname何时)。

最后的观察:

Which means dapper is not replacing the parameter with it's given value.

Dapper 从不 用给定的值替换参数。这根本不是参数化 sql 的正确方法:参数通常单独发送,确保:

  • 没有SQL注入(inject)风险
  • 最大查询计划重用
  • 没有格式问题

请注意,一些 ADO.NET/ODBC 提供程序理论上可以选择通过替换在内部实现某些东西 - 但这与 dapper 是分开的。

关于c# - Dapper 参数不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31755522/

相关文章:

dapper - 对于 varbinary 数据类型,DynamicParameters (Dapper) 的正确用法是什么?

c# - Dapper 出现 postgresql 错误(序列包含多个元素)

c# - 工作单元:Dapper和存储库模式-C#.Net

c# - 使用 Microsoft EntityFramework 进行单元测试

c# - 如何根据退出代码执行任意可执行文件和失败的 Cake 构建?

dapper - Dapper 如何在不显式打开连接的情况下执行查询?

c# - bool类型返回规则

c# - 如何在声明时使用其父实例实例化属性

c# - 测试 Powershell 脚本的正确性

c# - RDLC 在实时环境中将值乘以 100