2012-03-23 2 views
3

У меня есть следующий класс и объектыLINQ бросать запрос вложенных слишком глубоко исключений

Product{int ProdId{get; set;}, string ProdDesc{get; set;}} 

IQueryable<Product> products = ProductRepository.GetAllProducts(); 

List<int> filteredProdIds = new List<int>(); 

Метод GetAllProducts() выполняет несколько объединений по некоторым EF классов и дает обратно IQueryable<Product> объект. Я уже тестировал, возвращает ли он ожидаемые значения, и это так.

От products Я хочу, чтобы получить все записи, которые имеют свои ProdId в filteredProdIds (предположим, что filteredProdIds уже заполнены Ids):

products = products.Where(p => filteredProdIds.Any(fp => fp.Equals(p.ProdId))); 

Whn я запускаю мое приложение, оно бросает исключение

Некоторая часть вашего оператора SQL вложен слишком глубоко. Перепишите запрос или разделите его на более мелкие запросы.

Я пытался проверить запрос с LINQPad, заменив метод GetAllProducts() с эквивалентным зрения базы данных, и она работает.

Что может быть причиной этого исключения?

UPDATE

filteredProductIds заполняется этим методом:

IEnumerable<int> filteredProductIds = products.Select(p => p.partId).Distinct().ToList(); 

Я нашел способ избежать этого исключения, но должно быть намного чище решение:

foreach (var filteredProdId in filteredProdIds) 
{ 
    product.Union(product.Where(p => p.ProdId.Equals(filteredProdId))); 
} 
product.Distinct(); 
+2

Может быть, это может прояснить проблему: http://blog.hompus.nl/2010/08/26/joining-an-iqueryable- с-an-ienumerable/ – ilmatte

ответ

1

Там является лимит количества элементов в пределах filteredProdIds, так как это список.

Для тестирования вы можете установить filteredProdIds на:

filteredProdIds = filteredProdIds.Take(1).ToList(); 
+0

Что значит? Обычно вы указываете привязку к элементам при использовании массива, а список - динамический, поэтому теоретически нет верхней границы. – CiccioMiami

+0

@CiccioMiami. Если вы используете * linq-to-objects *, вы будете в порядке, но поскольку вы используете linq-to-entites, существует ограничение на размер списка. Чтобы проверить настройку try: * filterProdIds = filterProdIds.Take (1) .ToList(); * – Aducci

+0

извините, но я не понимаю вашу точку зрения. Я поставил часы, когда filterProdIds заполнен данными, и он правильно заполнен. – CiccioMiami

1
var filteredProdIds = FilterIds().ToArray(); 
var products = ProductRepository.GetAllProducts().Where(p => filteredProdIds.Contains(p.ProdId)); 
+0

Почему вы используете Contains непосредственно на filtersProdIds? Вы сравниваете int [] с int, это даст ошибку времени выполнения. Более того, если Contid, если ProdId = 2, выражение вернет true для всех значений filterProdIds, которые содержат 2, например 12, 20, 21, 22 и т. Д. – CiccioMiami

+2

Вы попробовали @CiccioMiami? Он должен перевести нечто вроде 'WHERE ProductId IN (1,2,3, ...'. 'IN' содержит целые числа, поэтому 2 не будет соответствовать 12. –

Смежные вопросы