28

一段时间以来,我一直在尝试在 Dapper中使用IEnumerable<string>with子句,但没有成功。WHERE IN

在文档中,它确实说IEnumerable<int>支持在 a 中使用,WHERE IN但我什至无法让它工作。

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

我不断收到的错误消息是 Sql 语法错误。Incorrect syntax near ','.

我整理了一些测试代码,希望能证明我想要实现的目标。


string connString = "Server=*.*.*.*;Database=*;User Id=*;Password=*;";

string sqlStringIn = @"SELECT StringText FROM 
                (SELECT 1 ID, 'A' StringID, 'This is a test' StringText
                UNION SELECT 2 ID, 'B' StringID, 'Another test' StringText
                UNION SELECT 3 ID, 'C' StringID, 'And another' StringText
                UNION SELECT 4 ID, 'D' StringID, 'and again' StringText
                UNION SELECT 5 ID, 'E' StringID, 'yet again' StringText) data
                WHERE StringId IN (@str)";

string sqlIntegerIn = @"SELECT StringText FROM 
                (SELECT 1 ID, 'A' StringID, 'This is a test' StringText
                UNION SELECT 2 ID, 'B' StringID, 'Another test' StringText
                UNION SELECT 3 ID, 'C' StringID, 'And another' StringText
                UNION SELECT 4 ID, 'D' StringID, 'and again' StringText
                UNION SELECT 5 ID, 'E' StringID, 'yet again' StringText) data
                WHERE ID IN (@integer)";


using (SqlConnection conn = new SqlConnection(connString))
{
    conn.Open();

    List<int> integers = new List<int>{ 1, 2, 3 };
    List<string> strings = new List<string> { "A", "B", "C" };

    var parameters = new {str = strings, integer = integers };

    //fails here
    IEnumerable<string> intTest = conn.Query<string>(sqlIntegerIn, parameters, commandType: System.Data.CommandType.Text);

    //and here
    IEnumerable<string> stringTest = conn.Query<string>(sqlStringIn, parameters, commandType: System.Data.CommandType.Text);

}
4

2 回答 2

56

为了做这里需要的事情,dapper 需要动态地改变 SQL - 所以它需要真正确定它正在做正确的事情。常规有效 SQL 语法包括括号:

WHERE StringId IN (@str)

为了消除歧义,voodoo dapper 语法 省略了括号:

WHERE StringId IN @str

如果检测到这一点,它会查找名为 的参数str,并将其扩展为以下之一:

WHERE 1=0 -- if no values
WHERE StringId = @str -- if exactly one value
WHERE StringId IN (@str0, @str1, ...) -- if more than one value

但简短的版本:删除括号。

于 2013-11-12T19:41:58.590 回答
3

如果您有兴趣能够处理空列表,我想添加一个重要说明,也就是 make the INclause optional。我通过添加一个包含计数的属性来做到这一点,例如public int InClauseCount => InClauseList?.Length ?? 0;

然后像这样使用sql中的计数......

Select field1, field2
from Table1
where (some condition)
AND (@InClauseCount = 0 OR field1 IN @InClauseList)

我希望这可以帮助那里的人。我花了太长时间试图解决这个问题,部分原因是我是 Dapper 的新手。

于 2017-11-29T11:45:36.940 回答