views:

369

answers:

4

Imagine you've got some Entity Framework entities that look like this (obviously not these specific classes, but the autogenerated ones with all the Entity Framework plumbing; these are just for illustration):

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

I have a LINQ query that looks like this:

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

However, this returns a list of Parents where the children are in ID order. I want the children to be sorted by their Number property within their Parent. How can this be done?

Edit: A clarification: the idea is to have the query hidden behind a method call (in the layer facade) that simply returns an IList<Parent>. This makes using solutions like anonymous class queries and manual sorting painful (compared to some panacea solution where you can just do it in the query or something).

A: 

Take a look at this post. You could try something like this:

var query = ((from parent in context.Parents
              from child in parent.Child
              orderby child.Number ascending
              select parent) as ObjectQuery<Parent>
            ).Include("Child");
Darin Dimitrov
Sorry Darin, I've tried your example and it doesn't work. The two from statements cause a join between Parent and Child and results in one parent per child returned. So you get returned each parent appearing multiple times and each containing all their (still unsorted) children!
Daniel Chambers
Look at this other tip: http://blogs.msdn.com/alexj/archive/2009/02/25/tip-1-sorting-relationships-in-entity-framework.aspx
Craig Stuntz
@Craig Stuntz: Craig, your link actually seems to be the answer to this problem (or non-answer, really!) direct from the Microsoft dudes. You should submit it as an answer and I'll accept it.
Daniel Chambers
A: 

One option is executing the query and sorting in memory (e.g. on output).

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

There are two other options that also seem to work with their own pros and cons:

http://stackoverflow.com/questions/1155757/linq-include-orderby-in-subquery

http://stackoverflow.com/questions/1304556/linq-orderby-name-thenby-childrencollection-name

mkedobbs
Thanks for your suggestions! However, I think your first one is a bit clunky since it requires you to manually order stuff, which defeats the purpose of making the DB do it (and the added neatness) with a LINQ query.The first link's accepted solution doesn't actually work (I've put a comment on that, so have a look).The second link seems to be talking about sorting the parents by the children and then selecting the children, which isn't what I'm looking for.I'm looking for a neat panacea solution, and judging by your answer and the other answers, it simply doesn't exist for Entity Framework
Daniel Chambers
I think you're right... at least not in the version that ships with 3.5. Don't know about 4.0 yet...
mkedobbs
A: 

here is something that I have done:

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

I implememented something like this and it worked very well for me

Luke101
Thanks for the suggestion, however, I don't want to use an anonymous class. My database code is hidden in its own layer, so I have a method call that returns a IList<Parent>. To achieve this using anonymous classes is clunky as I'd have to manually reconstruct the object tree (manually put children into Parents then return the Parents). This defeats the purpose of having Entity Framework and LINQ manage the relationships and object graph creation for me.
Daniel Chambers
+1  A: 

Alex James discusses this issue in this tip.

Essentially, relationships are considered as unordered, per standard relational modeling. So you can't get them sorted. But you can project onto other collections, which can be sorted.

Craig Stuntz
Also, you can't read them in unordered, take them out of their EntityCollection, manually sort them, and put them back into their EntityCollection (assuming NoTracking is on, of course). When you then iterate over the EntityCollection, they come out out of order anyway. :(
Daniel Chambers
Right, because `EntityCollection`s are *unordered.*
Craig Stuntz