Как использовать IN() для поиска существования?

#c# #npgsql

#c# #npgsql

Вопрос:

Я использую Npgsql для подключения к базе данных Postgres, и я хочу выполнить запрос, подобный этому:

  SELECT column IN('foo', 'bar') FROM table;
  

чтобы проверить, есть ли столбец в списке.

Теперь у меня есть этот код на C #:

 var list = new string[] { "foo", "bar" };
var cmd = new NpgsqlCommand("SELECT column IN(:list) FROM table", myConnection);
cmd.Parameters.AddWithValue("list", list);
  

Но это не работает, поскольку Npgsql создает ARRAY from list , где это должно быть что-то другое, … но что?

Комментарии:

1. 'foo', 'bar' — это опечатка? Должно быть var list = new string[] { "foo", "bar" };

2. @Dennis да, это опечатка; это то, что вы получаете за смешивание языков :).

3. Возможно, стоит изучить Dapper, чтобы упростить подобные вещи.

Ответ №1:

Я исправил это с помощью ANY оператора, так как он принимает массив:

 var list = new string[] { "foo", "bar" };
var cmd = new NpgsqlCommand("SELECT column = ANY(:list) FROM table", myConnection);
cmd.Parameters.AddWithValue("list", list);
  

Ответ №2:

Каждый элемент должен передаваться как отдельный параметр.

Их можно создавать динамически, проецируя ваш список в параметры:

 var list = new string[] { "foo", "bar" };
var parameters = list.Select((x, i) => new NpgsqlParameter($"@item{i}", x));
var cmd = new NpgsqlCommand($@"
    SELECT column IN({string.join(',', parameters.Select(x => x.ParameterName))})
    FROM table", myConnection);
cmd.Parameters.AddRange(parameters);
  

Комментарии:

1. Объединение литеральных значений в вашем SQL означает, что вы не можете повторно использовать одни и те же планы запросов с помощью подготовленных операторов. Обычно лучше параметризовать массив с помощью ANY, как показано выше.