LINQ Query - как сортировать и фильтровать при активном извлечении - PullRequest
1 голос
/ 16 марта 2011

Как выполнить активный запрос родительских и дочерних отношений, который:

  1. фильтрует a по дочерним полям
  2. сортирует как по родительскому, так и по дочернему
  3. returna List или Parents с предварительно заполненными детьми

Если я попытаюсь

from p in _context.Parents.Include("children")
join c in _context.childrenon p.Id equals c.ParentId 
where d.DeletedDate == null
orderby p.Name ascending, c.Name 
select p

Затем я получу объект Parent обратно, но у каждого Родителя есть NULL для детей

если я попытаюсь

from p in _context.Parents.Include("children")
orderby p.Name ascending
select p

Запрос возвращает всех родителей и детей, но они не отфильтрованы и не отсортированы.

Результат, который я хочу получить, - IEnumerable<Parent>, то есть

Parent[0].name = "foo"
Parent[0].children = IEnumerable<Child>
Parent[1].name = "bar"
Parent[1].children = IEnumerable<Child>

Ответы [ 3 ]

10 голосов
/ 16 марта 2011

Нет прямого способа сделать это, но вы можете использовать какой-то обходной путь - спроецируйте родителя и потомков на анонимный объект, а затем выберите и верните родителя из объекта.

См. Аналогичный вопрос: Linq To Entities - как фильтровать дочерние сущности

В вашем случае у вас будет что-то вроде:

var resultObjectList = _context.
                       Parents.
                       Where(p => p.DeletedDate == null).
                       OrderBy(p => p.Name).
                       Select(p => new
                                 {
                                     ParentItem = p,
                                     ChildItems = p.Children.OrderBy(c => c.Name)
                                 }).ToList();

List<Parent> resultingCollection = resultObjectList.Select(o => o.ParentItem).ToList();
1 голос
/ 16 марта 2011

Решение зависит от того, что именно вы пытаетесь сделать.

Первый запрос создает впечатление, что вы хотите «сгладить» результаты в объектах, как это (псевдокод, надеюсь, понятно, чтоЯ имею в виду):

{ Parent1, Child1 }
{ Parent1, Child2 }
{ Parent1, Child3 }
{ Parent2, Child1 }

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

Второй запрос просто возвращает объекты Parent и (вы не показываете это, но я предполагаю, что EF был проинструктирован об этом), у каждого есть коллекция Children.В этом случае вы можете сортировать только по родительскому имени;если вы хотите отсортировать дочерние элементы каждого Parent, отсортируйте коллекцию Children по этому объекту отдельно.

Что из двух вы хотите сделать?

Обновление

ОК, похоже, вам нужен второй.Я не верю, что это можно сделать напрямую.Вы можете просто сделать это при перечислении результатов - поскольку Parent s уже отсортированы, просто отсортируйте дочерние элементы каждого:

var sortedChildren = parent.Children.OrderBy(c => c.Name);
0 голосов
/ 16 марта 2011

предварительная выборка дочерних полей:

using (BlogDataContext context = new BlogDataContext())
{
    DataLoadOptions options = new DataLoadOptions();
    options.LoadWith<Blog>(c => c.Categories);
    options.LoadWith<Blog>(c => c.Title);
    context.LoadOptions = options;
    Blog blog = context.Blogs.Single<Blog>(c => c.BlogId == 1);
}
...