#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, как показано выше.