Как передать список в качестве параметра в .NET - PullRequest
4 голосов
/ 21 сентября 2009

У меня есть запрос, который в основном похож на это:

SELECT foo
FROM bar
where bar.Id in (1,2,3);

Я хотел бы передать список идентификаторов в виде одного параметра с IDbDataParameter, где запрос отформатирован:

SELECT foo
FROM bar
where bar.Id in (?ListOfID);

и затем используйте один параметр, который представляет собой список, вместо того, чтобы делать что-то вроде этого:

SELECT foo
FROM bar
where bar.Id in (?id1, ?id2, ?id3);

Я знаю, что это возможно в других провайдерах данных. Могу ли я сделать это с помощью стандартных классов System.Data?

P.S. причина, по которой я хочу использовать его в качестве одного параметра списка, а не ряда параметров, заключается в том, что при изменении количества параметров MySQL будет рассматривать запрос как новый, и мы теряем некоторые оптимизации кэширования. MySQl в основном заканчивается одним запросом на количество идентификаторов. Это та же самая причина, по которой я не хочу манипулировать базовым SQl как строкой, потому что тогда я получаю один запрос на VAULE, и это будет хуже.

Ответы [ 4 ]

2 голосов
/ 21 сентября 2009

Можно ли использовать:

string[] myParamaters = new string[2];
myParameters[0] = "id1"
myParameters[1] = "id2"

После создания массива и его заполнения так, как вы хотите:

SELECT foo
FROM bar
where bar.Id in (string.Join(", ", myParameters));

Я не совсем уверен, что это было то, о чем вы спрашивали, но я думаю, это то, что я понял из вашего поста.

0 голосов
/ 22 сентября 2009

Мне неясно, говорите ли вы о LINQ, но если это так, вам следует перевернуть его и использовать Contains ().

var whatever = from bar in bars
               where ListOfID.Contains(bar.Id)
               select bar;

Да, список преобразуется в динамический sql, но, по крайней мере, вам не придется возиться с экранированием / манипуляциями со строками самостоятельно.

Насколько я знаю, sql вообще не может принимать массивы в качестве параметров для функций / процедур, поэтому я сомневаюсь, что кэшированные планы выполнения могут даже выразить идею массива.

Если у вас есть разумное количество элементов, вы можете «перегрузить» sproc для каждого количества параметров до определенного числа, за пределами которого это будет обычный динамический путь.

StuffWithList1 one
StuffWithList2 one two
StuffWithList3 one two three

ИЛИ, просто

StuffWithList one two three four five six seven eight nine ten eleven ... twenty

и передать пустые значения для ненужных параметров:

StuffWithList 8 9 3 null null null null null null null null ... null
0 голосов
/ 22 сентября 2009

Вы можете передать список с разделителями и использовать функцию табличной переменной, чтобы «разбить» список на строки.

Я разместил пример здесь .

0 голосов
/ 21 сентября 2009

Если я правильно понимаю, вы хотите передать в свой запрос один параметр и разбить его на что-то, что можно использовать с оператором IN. В прошлом я использовал строковый параметр и заполнил его списком с разделителями-запятыми (разделитель может быть любым), а затем создал функцию sql, чтобы превратить список с разделителями-запятыми в таблицу. Я использовал таблицу, выведенную из функции sql с оператором IN.

Я использовал MS Sql Server, поэтому не уверен, возможно ли это в MYSQL. Если бы это было что-то вроде

ВЫБРАТЬ ФУ ОТ бара где bar.Id in (SELECT * FROM ConvertToTableFunctionOrProc (? DelimitedList,? Delimiter));

Функция создает таблицу с одним столбцом и одной строкой для каждого значения в списке с разделителями. Не знаю, можно ли это сделать в MySQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...