Sorting by Children in Entity Framework doesn't return sorted list

Viewed 147

I know that Entity framework doesn't support sort or filter in the children collections yet. What I thought is that first I get the data then use foreach loop to sort it. The result gives me an unsorted list. My goal is to get the Participants (any order) and CurrentHospitaliztions (order by id descending) which is a child of participants. The models and the query is below. Any help will be appriciated.

public class Participant
{
    public int Id { get; set; }
    .. other fields

    public ICollection<CurrentHospitalization> CurrentHospitalizations { get; set; }

    public Participant()
    {
        CurrentHospitalizations = new Collection<CurrentHospitalization>();
    }
}

public class CurrentHospitalization
{
    public int Id { get; set; }
    .. other fields

    public Participant Participant { get; set; }
    public int ParticipantId { get; set; }

}

The query that I use:

public async Task<IEnumerable<Participant>> GetList()
{
     var participants = await context.Participants
        .Include(x => x.CurrentHospitalizations)
        .ToListAsync();

        foreach (var p in participants )
        {
            var s = p.CurrentHospitalizations;
            foreach (var q in s)
            {
                s.OrderByDescending(u => u.Id);
            }
        }

        return participants ;
}
2 Answers

You sorted the right piece, in the wrong place, and then didn't really do anything with it. You don't need the nested iteration, you can just do it from the single foreach loop like this:

foreach (var p in participants) 
    p.CurrentHospitalizations = p.CurrentHospitalizations.OrderByDescending( ch => ch.Id ).ToList();

What you ahve here is a failure to understand the basics of LINQ and not reading the manual.

        var s = p.CurrentHospitalizations;
        foreach (var q in s)
        {
            s.OrderByDescending(u => u.Id);
        }

does effectively nothing else than waste processor time.

You make a variable s. You assign to it the current hospuzatlizations, not sorted.

Then you call OrderByDescending - generating an expression that you COULD execute, except you never DO execute it. So, you created some object tree and - throw it away.

o.CurrentHospitalizations = s.OrderByDescending(u => u.Id).ToList()

would assign s to be a list and execute it. The ToList() is missing - as well as the assigning it, so the sorted result is not just thrown away.

Those are LINQ basics - orderby etc. are not changing order, they return an ordered result, and you must materialize it.

Related