LINQ Query - how sort and filter on eager fetch

白昼怎懂夜的黑 提交于 2019-12-18 07:17:09

问题


How do I do a eager query of a parent child relationship that:

  1. filters a on child fields
  2. sorts on both parent and child
  3. return a List or Parents with the children pre-populated

If I try

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

Then I get the Parent object back but each Parent has NULL for children

if I try

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

The query returns all Parents and children but they are not filtered or sorted.

The result I want back is a IEnumerable<Parent> i.e.

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

回答1:


The solution depends on what exactly you are trying to do.

The first query gives the impression that you want to "flatten out" the results in objects, like this (pseudocode, I hope it's clear what I mean):

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

In this case each result "row" would be an object having a Parent and a Child property, and you could sort by parent name and then by child name.

The second query just returns the Parent objects and (you don't show it but I assume EF has been instructed to do that) each one has a Children collection. In this case you can only sort by parent name; if you want to sort each Parent's children, sort the Children collection on that object by itself.

Which of the two do you want to do?

Update

OK, it seems you want the second one. I don't believe it can be done directly. You can just do it when you enumerate the results - since the Parents are already sorted, simply sort each one's children:

var sortedChildren = parent.Children.OrderBy(c => c.Name);



回答2:


There is no direct way of doing this, but you can use somewhat of a workaround - project the parent and children onto an annonymous object and then select and return the parent from the object.

See similar question: Linq To Entities - how to filter on child entities

In your case you will have something along the lines of:

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();



回答3:


prefetching child fields:

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);
}


来源:https://stackoverflow.com/questions/5324931/linq-query-how-sort-and-filter-on-eager-fetch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!