小巧的参数不起作用

Bit*_*ler 7 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
    });            
Run Code Online (Sandbox Code Playgroud)

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


EDIT1

无法让这个工作.使用string.format将参数作为解决方法插入.

Mar*_*ell 16

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

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

...
where a.acct = ?
Run Code Online (Sandbox Code Playgroud)

在你的命令中,和:

var result = connection.Query(sqlString.ToString(),
new {
    anythingYouLike = accountNumber
});
Run Code Online (Sandbox Code Playgroud)

请注意,anythingYouLikeODBC不使用name(),因此可以... 您喜欢的任何内容.在更复杂的场景中,例如:

.Execute(sql, new { id = 123, name = "abc", when = DateTime.Now });
Run Code Online (Sandbox Code Playgroud)

短小精悍使用的是如何实现的匿名类型,了解值的原始顺序,让他们以正确的顺序(添加到命令的一些知识id,name,when).

最后一点观察:

这意味着dapper没有用它给定的值替换参数.

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

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

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