Как использовать "Where In" в Dapper
Я пробовал безуспешно некоторое время использовать IEnumerable<string>
с предложением WHERE IN
в Dapper.
В документации говорится, что 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);
}
Ответы
Ответ 1
Чтобы делать то, что здесь необходимо, 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
Но короткая версия: удалите скобки.
Ответ 2
Я хочу добавить важную заметку, если вы заинтересованы в возможности обрабатывать пустой список, а также сделать предложение 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.