Я экспериментирую с LINQ уже некоторое время.
Типичный метод для перечисления в коллекции и изменения некоторых ее свойств в моем коде будет выглядеть так:
ATDataContext dc = new ATDataContext(Settings.connection_string);
int[] col = ListViewClass.getListViewSelectedPositionTags(listView);
try
{
foreach (var item in col)
{
var ctx = (from r in dc.MailingLists
where r.ID == item
select r).Single();
ctx.Excluded = 'Y';
ctx.ExcludedComments = reason;
}
dc.SubmitChanges();
}
Некоторое время у меня есть совет сделать это ... кажется более умным способом:
var ctx = from r in dc.MailingLists
where col.Contains(r.ID)
select r;
foreach (var item in ctx)
{
item.Excluded = 'Y';
item.ExcludedComments = reason;
}
dc.SubmitChanges();
Это имеет смысл на многих уровнях, и мне нравится это решение. Он умнее и быстрее первого.
Я какое-то время использовал это решение в производственной среде.
Что меня удивило после нескольких недель поиска файлов журнала приложения и просмотра этого:
"Неверный поток протокола удаленного вызова процедур (RPC) входящего потока табличных данных (TDS). Слишком много параметров было предоставлено в этом запросе RCP. Максимум - 2100."
LINQ to SQL преобразует предложение where col.Contains(r.ID)
в IN
, похожее на:
ГДЕ ИДЕНТИФИКАЦИЯ (@ p1, @ p1, @ p2…)
Коллекция col
достигла (в моем случае) более 2100 элементов, и запрос не был выполнен. Я провел некоторое исследование по проблеме, и в итоге я получил:
«… Максимальное количество параметров в запросе sql составляет 2100. Существуют дополнительные ограничения, например тот факт, что вся строка запроса не может быть длиннее 8044 символов.»
Мне так понравилось второе решение. Я так разочарован этими жестко заданными ограничениями SQL Server.
Я что-то пропустил?
Могу ли я что-нибудь сделать, чтобы использовать версию “where col.Contains (r.ID)”?
С уважением
Мариуш
пс. (Я использую Win XP, C # с LINQ и SQL 2005 Express).