如何在Dapper中使用’Where In’
我一直试图在Dapper中使用带有WHERE IN
子句的IEnumerable
一段时间失败。
在文档中,它确实支持在WHERE IN
使用IEnumerable
,但我甚至无法使其工作。
Dapper allow you to pass in IEnumerable 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 integers = new List{ 1, 2, 3 }; List strings = new List { "A", "B", "C" }; var parameters = new {str = strings, integer = integers }; //fails here IEnumerable intTest = conn.Query(sqlIntegerIn, parameters, commandType: System.Data.CommandType.Text); //and here IEnumerable stringTest = conn.Query(sqlStringIn, parameters, commandType: System.Data.CommandType.Text); }
为了做到这里需要的东西,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
但是短版本:删除括号。
如果您对能够处理空列表感兴趣,我想添加一个重要的注释,即使IN
子句optional
。 我这样做是通过添加一个属性来包含计数,例如public int InClauseCount => InClauseList?.Length ?? 0;
public int InClauseCount => InClauseList?.Length ?? 0;
然后像这样在sql中使用count …
Select field1, field2 from Table1 where (some condition) AND (@InClauseCount = 0 OR field1 IN @InClauseList)
我希望这可以帮助那里的人。 我花了一点时间试图解决这个问题,部分是因为我是Dapper的新手。