Dapper 和列表参数 return ',' 附近的语法不正确

Dapper and list parameters return Incorrect syntax near ','

我有以下使用 Dapper 的代码:

public async Task GetClientsInvoices(List<long> clients, List<int> invoices)
{
    var parameters = new
    {
        ClientIds = clients,
        InvoiceIds = invoices
    };

    string sqlQuery = "SELECT ClientId, InvoiceId, IsPaid" +
                       "FROM ClientInvoice " +
                       "WHERE ClientId IN ( @ClientIds ) " +
                       "AND InvoiceId IN ( @InvoiceIds )";

    var dbResult = await dbConnection.QueryAsync<ClientInvoicesResult>(sqlQuery, parameters);
}

public class ClientInvoicesResult
{
    public long ClientId { get; set; }

    public int InvoiceId { get; set; }

    public bool IsPaid { get; set; }
}

它基于 sql server profiler

产生这个
exec sp_executesql N'SELECT ClientId, InvoiceId, IsPaid FROM ClientInvoice WHERE ClientId IN ( (@ClientIds1) ) AND InvoiceId IN ( (@InvoiceIds1,@InvoiceIds2) )',N'@InvoiceIds1 int,@InvoiceIds2 int,@ClientIds1 bigint',InvoiceIds1=35,InvoiceIds2=34,ClientIds1=4

执行时出现以下错误

Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.

我有两个问题:

  1. 我做错了什么,我得到了这个异常?

  2. 为什么 dapper 翻译这个查询并使用 sp_executesql 执行它。我如何强制它使用正常的 select 查询,如

    SELECT ClientId, InvoiceId, IsPaid 来自客户发票 其中 ClientId 在 (4) 和 InvoiceId 在 (34,35)

尝试将列表转换为字符串并作为逗号分隔的字符串传递:

var parameters = new
    {
        ClientIds = String.Join(",",clients),
        InvoiceIds = String.Join(",",invoices)
    };

正在查看您的个人资料SQL:

exec sp_executesql
    N'SELECT ClientId, InvoiceId, IsPaid
        FROM ClientInvoice
        WHERE ClientId IN ( (@ClientIds1) )
        AND InvoiceId IN ( (@InvoiceIds1,@InvoiceIds2) )',
    N'@InvoiceIds1 int,@InvoiceIds2 int,@ClientIds1 bigint',InvoiceIds1=35,InvoiceIds2=34,ClientIds1=4

我们可以看到您在 @ClientIds1@InvoiceIds1,@InvoiceIds2 周围有两组括号,一组是您编写的,另一组是 Dapper(或它下面的一层)正在注入的.

因此,请尝试删除您添加的括号:

string sqlQuery = "SELECT ClientId, InvoiceId, IsPaid " +
                   "FROM ClientInvoice " +
                   "WHERE ClientId IN @ClientIds " +
                   "AND InvoiceId IN @InvoiceIds";

这与 Dapper README 中的代码匹配:

Dapper allows you to pass in IEnumerable<int> and will automatically parameterize your query.

For example:

connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { 1, 2, 3 } });

Will be translated to:

select * from (select 1 as Id union all select 2 union all select 3) as X where Id in (@Ids1, @Ids2, @Ids3)" // @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3

删除括号即可解决问题。

错误:“WHERE ClientId IN (@ClientIds)”

更正:“WHERE ClientId IN @ClientIds”