Вопрос по linq-to-sql – Обход LinqToSQls исключения «запросы с локальными коллекциями не поддерживаются»

36

Итак, я пытаюсь вернуть коллекцию людей, чей идентификатор содержится в локально созданной коллекции идентификаторов (IQueryable)

Когда я указываю «локально созданную коллекцию», я имею в виду, что коллекция Ids не пришла из запроса LinqToSql и была создана программно (на основе пользовательского ввода). Мой запрос выглядит так:

var qry = from p in DBContext.People
                  where Ids.Contains(p.ID)
                  select p.ID;

Это вызывает следующее исключение ...

& quot; запросы с локальными коллекциями не поддерживаются & quot;

Как я могу найти всех людей с идентификатором, который содержится в моей локальной коллекции идентификаторов?

Возможно ли использовать LinqToSql?

Ваш Ответ

4   ответа
0

но ответы здесь не работают для меня, поскольку я делаю динамические типы в дальнейшем.

Что я сделал, так это использовал "UNION" в цикле, который прекрасно работает. Вот как:

var firstID = cityList.First().id;
var cities = dc.zs_Cities.Where(c => c.id == firstID);
foreach(var c in cityList)
{
  var tempCity = c;
  cities = cities.Union(dc.zs_Cities.Where(cty => cty.id == tempCity.id));
}
29

ny () вместо

people.Where(x => ids.Any(id => id == x.ID))
@maxlego И сгенерированный SQL является спуском. Спасибо
35

массивом или подобным, L2S преобразуется в содержимое.

Если Ids является IQueryable, просто включите его в список, прежде чем использовать его в запросе. Например.:

List<int> listOfIDs = IDs.ToList();  
var query =  
from st in dc.SomeTable  
where listOfIDs.Contains(st.ID)
select .....
@jmbledsoe, если мой ответ был недостаточно ясен: L2S ожидает, что локальный IEnumerable (не отложенный IQueryable) передается в Enumerable.Contains. Если вы передаете ему локальный запрос, он не может быть преобразован в запрос SQL. Если вы передадите ему список / массив / и т. Д., То его можно будет преобразовать в SQL "где ... in (x, y, ..., n)" пункт.
Раннее разрешение ваших IQueryables может привести к серьезным сбоям в производительности. Попробуйте сначала использовать Any () вместо Contains ().
Я думаю, что вижу, что вы говорите: - Передача списка / массива / и т. Д. все в порядке, потому что он сгенерирует предложение WHERE ... IN. - Передача отложенного IQueryable - это нормально, т.к. он будет интегрирован с текущим отложенным запросом. - Передача локального IEnumerable НЕ ОК, но вы можете просто .ToList (), и все будет хорошо.
Если listOfID - это сотни или тысячи элементов, вы можете проверить ответ @ maxlego, который мне помог
Я думаю, что решение вашей проблемы более нюанс, чем этот ответ. Я успешно использую ту же конструкцию (метод Contains для IQueryable в предложении WHERE), а LINQ to SQL переводит его в предложение WHERE EXISTS в запросе SQL. Похоже, что это работает в некоторых ситуациях, а не в других, поэтому вы должны опубликовать, как вы получаете Id IQueryable, поскольку это может пролить свет на проблему.
1

преобразование идентификаторов, имеющих тип IQueryable в List или Array, решит проблему, это будет преобразовано в «IN». Оператор в SQL. Но будьте осторожны, потому что, если число идентификаторов & gt; = 2100, это вызовет другую проблему, которая "Сервер поддерживает максимум 2100 параметров". и это максимальное количество параметров (значений), которое вы можете передать в «IN»; в SQL-сервере.

Другой альтернативой будет сохранение идентификаторов IQueryable и использование LINQ «Любой». оператор вместо «Содержит», это будет переведено как «СУЩЕСТВУЕТ» в SQL-сервере.

Похожие вопросы