如何在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的新手。