Название вашего вопроса заинтриговало меня словами "Безумный запрос", и да, вы правы, это немного сумасшедший.
У вас есть предложение .Where(...)
со следующим предикатом:
ch => ch.ParentCategoryID == ch.ParentCategoryID
Теперь это всегда будет правдой. Итак, я думаю, что вы пытаетесь сделать что-то еще. Я пойму, что это может быть в конце моего ответа.
Затем я немного очистил ваш запрос, чтобы лучше понять, что вы делаете. Вот как это выглядит сейчас:
var query =
context
.Categories
.Where(c => context
.CategoryHierarchy
.Select(ch => ch.ChildCategoryID)
.Contains(c.CategoryID));
Поэтому вместо использования вложенных запросов я бы предложил что-то вроде этого, может быть лучше с точки зрения читабельности и, возможно, производительности:
var query =
from c in context.Categories
join h in context.CategoryHierarchy
on c.CategoryID equals h.ChildCategoryID into ghs
where ghs.Any()
select c;
Это дает те же результаты, что и ваш запрос, так что, надеюсь, это полезно.
У меня складывается впечатление, что вы пытаетесь выполнить запрос, в котором вы хотите вернуть каждую категорию вместе с любыми дочерними категориями, которые у нее могут быть. Если это так, то вот запросы, которые вам нужны:
var lookup =
(from c in context.Categories
join h in context.CategoryHierarchy
on c.CategoryID equals h.ChildCategoryID
select new { ParentCategoryID = h.ParentCategoryID, Category = c, }
).ToLookup(x => x.ParentCategoryID, x => x.Category);
var query =
from c in context.Categories
select new { Category = c, Children = lookup[c.CategoryID], };
Запрос lookup
сначала объединяет категории и иерархии категорий для возврата всех дочерних категорий и связанных с ними ParentCategoryID
, а затем создает поиск из ParentCategoryID
в список связанных Category
дочерних элементов.
Запрос теперь просто должен выбрать все категории и выполнить поиск по CategoryID
, чтобы получить детей.
Преимущество использования подхода .ToLookup(...)
состоит в том, что он легко позволяет включать категории, у которых нет детей. В отличие от использования Dictionary<,>
, поиск не выдает исключение, когда вы используете ключ, для которого у него нет значения - вместо этого он возвращает пустой список.
Теперь вы можете добавить обратно в .Include(...)
вызовы тоже.
var lookup =
(from c in context.Categories
.Include("ChildHierarchy")
.Include("otherprop")
join h in context.CategoryHierarchy
on c.CategoryID equals h.ChildCategoryID
select new { ParentCategoryID = h.ParentCategoryID, Category = c, }
).ToLookup(x => x.ParentCategoryID, x => x.Category);
var query =
from c in context.Categories
.Include("ChildHierarchy")
.Include("otherprop")
select new { Category = c, Children = lookup[c.CategoryID], };
Это то, что вы ищете?