LINQ查询 - 如何对急切提取进行排序和过滤

时间:2011-03-16 12:01:07

标签: linq entity-framework-4 linq-to-entities

如何对父子关系进行急切查询:

  1. 过滤子字段
  2. 对父母和孩子进行排序
  3. 返回已预先填充子项的列表或父母
  4. 如果我尝试

    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对象,但是每个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 个答案:

答案 0 :(得分:9)

没有直接的方法可以做到这一点,但您可以使用某种解决方法 - 将父项和子项投影到一个匿名对象上,然后从对象中选择并返回父项。

查看类似问题:Linq To Entities - how to filter on child 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 :(得分:1)

解决方案取决于您的具体目标。

第一个查询给人的印象是你想要“平掉”对象中的结果,就像这样(伪代码,我希望它清楚我的意思):

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

在这种情况下,每个结果“row”都是一个具有ParentChild属性的对象,您可以按父名称排序,然后按子名称排序。

第二个查询只返回Parent个对象(你没有显示它,但我认为EF已被指示这样做)每个对象都有一个Children集合。在这种情况下,您只能按父名称排序;如果要对每个Parent个孩子进行排序,请自行对该对象上的Children集合进行排序。

你想做哪两个?

<强>更新

好的,好像你想要第二个。我不相信它可以直接完成。您可以在枚举结果时执行此操作 - 因为Parent已经排序,只需对每个孩子进行排序:

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

答案 2 :(得分:0)

预取子字段:

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