我现在一直试图在Dapper中使用带有IEnumerable<string>
子句的WHERE IN
一段时间失败。
在文档中,它确实支持在IEnumerable<int>
中使用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);
}
答案 0 :(得分:48)
为了做到这里需要的东西,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
但是短版本:删除括号。
答案 1 :(得分:1)
如果您对能够处理空列表感兴趣,我想添加一个重要的注释,即创建IN
子句optional
。我这样做是通过添加一个属性来包含计数,例如public int InClauseCount => InClauseList?.Length ?? 0;
然后在sql中使用这样的计数......
Select field1, field2
from Table1
where (some condition)
AND (@InClauseCount = 0 OR field1 IN @InClauseList)
我希望这可以帮助那里的人。我花了一点时间试图解决这个问题,部分原因是因为我是Dapper的新手。