2009-12-06 62 views
3

想象一下,你已经有了一些看起来像这样的Entity Framework实体(显然不是这些特定的类,而是自动生成的所有实体框架管道的实体;这些只是为了说明):使用LINQ-to-Entities选择父项时排序子对象

public class Parent 
{ 
    public int ID { get; set; } 
    public List<Child> Children { get; set; } 
} 

public class Child 
{ 
    public int ID { get; set; } 
    public Parent Parent { get; set; } 
    public int Number { get; set; } 
} 

我有一个LINQ查询,看起来像这样:

from parent in context.Parents.Include("Child") 
select parent 

然而,这将返回那里的小朋友都在ID为了父母的列表。我希望孩子们可以在其父母的数字属性中进行排序。 这怎么办?

编辑:澄清:这个想法是让查询隐藏在方法调用(在图层外观)后面,该方法调用简单地返回IList<Parent>。这使得像匿名类查询和手动排序这样的解决方案变得痛苦(与一些万能解决方案相比,您可以在查询中完成它)。

回答

3

亚历克斯詹姆斯在this tip讨论这个问题。

基本上,关系被认为是无序的,每个标准的关系建模。所以你不能对它们进行排序。但是你可以投射到其他收藏,其中可以排序。

+0

另外,您无法在无序中读取它们,将它们从EntityCollection中取出,手动对它们进行排序,然后将它们放回到它们的EntityCollection中(当然假设NoTracking处于打开状态)。当你迭代EntityCollection时,它们无论如何都会出错。 :( – 2009-12-11 13:09:55

+0

对,因为'EntityCollection's *无序。* – 2009-12-11 13:30:07

0

看看这个post。你可以尝试这样的:

var query = ((from parent in context.Parents 
       from child in parent.Child 
       orderby child.Number ascending 
       select parent) as ObjectQuery<Parent> 
      ).Include("Child"); 
+0

对不起达林,我试过你的例子,它不起作用。这两个from语句导致Parent和Child之间的连接,并导致每个孩子返回一个父级。所以你会得到返回的每个家长出现多次,每个包含他们所有(仍未排序)的孩子! – 2009-12-06 09:13:03

+1

看看另一个提示:http://blogs.msdn.com/alexj/archive/2009/02/25/tip-1-sorting-relationships-in-entity-framework.aspx – 2009-12-09 13:55:23

+0

@克雷格Stuntz:克雷格,你的链接实际上似乎是直接从微软官员那里得到的答案(或者是非答案,真的!)。你应该提交它作为答案,我会接受它。 – 2009-12-10 02:03:37

0

一个选项是执行内存中的查询和排序(例如输出)。

var parents = context.Parents.Include("Child").ToList(); //note that ToList is here just to execute the query and get the objects in memory 

foreach (var p in parents) 
{ 
    //do something with parent item 
    foreach (var c in p.Child.OrderBy(c => c.Number)) 
    { 
     /do something with the child item 
    } 
} 

有迹象表明,似乎也有自己的优点和缺点,以工作的其他两个选项:

LINQ ".Include" orderby in subquery

LINQ OrderBy Name ThenBy ChildrenCollection.Name

+0

感谢您的建议!不过,我认为你的第一个有点笨拙,因为它需要你手动排列东西,这使得DB使用LINQ查询来做到这一点(并且增加了整洁性)。 第一个链接可接受的解决方案实际上并不奏效(我已对此发表了评论,所以看看)。 第二个环节似乎是在谈论孩子们分拣父母,然后选择孩子,这不是我正在寻找的。 我正在寻找一个整洁的万灵丹解决方案,并根据您的答案和其他答案来判断,它根本不存在于实体框架中 – 2009-12-10 02:00:42

+0

我认为您是对的......至少在版本中不包含3.5 。不知道大约4.0还有... – mkedobbs 2009-12-10 16:28:54

0

这里的东西,我已经做了:

var query = from parent in context.Parents 
      select new 
      { 
       parent, 
       childs = from child in context.Child 
          orderby child.ID ascending 
          select new 
          { 
           child 
          } 
      } 

我实现了像t他和我的工作非常好

+0

感谢您的建议,但是,我不想使用匿名类。我的数据库代码隐藏在它自己的层中,所以我有一个返回IList 的方法调用。为了实现这一点,使用匿名类是笨拙的,因为我不得不手动重建对象树(手动将孩子放入父母然后返回父母)。这违背了让Entity Framework和LINQ为我管理关系和对象图创建的目的。 – 2009-12-10 01:43:54