Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation of List<T> is losing the ordering on the original query

Using Entity Framework I have an IQueryable for a database object Meeting and e is the DbContext.

IQueryable<Meeting> meetings = e.Meetings
    .Include(m => m.MeetingStage)
    .Include(m => m.MeetingType)

This query has had OrderBy applied.

I then want to select from this query into a new object MeetingSearchResult. However, I'm finding that in certain cases the ordering is being changed, as these tests demonstrate

var temp2 = sortedMeetings.Select(m => m.MeetingID);

System.Diagnostics.Debug.WriteLine(string.Join(" / ", temp2.ToList().ToArray()));

var temp4 = sortedMeetings.Select(m => new MeetingSearchResult()
{
       MeetingID = m.MeetingID,
       CompanyName = m.CompanyName
});

System.Diagnostics.Debug.WriteLine(string.Join(" / ", temp4.ToList().Select(m => m.MeetingID).ToArray()));

var temp8 = sortedMeetings.Select(m => new MeetingSearchResult()
{
      MeetingID = m.MeetingID,
      CompanyName = m.CompanyName,
      MeetingDate = m.MeetingDate,
      MeetingStage = m.MeetingStage.Description
});

System.Diagnostics.Debug.WriteLine(string.Join(" / ", temp8.ToList().Select(m => m.MeetingID).ToArray()));

The output of the debuggers here is:

2493 / 4228 / 7029 / 8254 / 9375 / 10563 / 11716 / 10500
2493 / 4228 / 7029 / 8254 / 9375 / 10563 / 11716 / 10500
2493 / 4228 / 7029 / 8254 / 9375 / 10500 / 10563 / 11716

The order of objects in temp8 has changed. Can anyone explain this?

More info:

People have asked for more info about what sortedMeetings is.

var sortedMeetings = meetings.DoMeetingSort(sort, ascending);

My extension DoMeetingSort follows. I've removed the switch cases that do not apply here:

    public static IQueryable<Meeting> DoMeetingSort(this IQueryable<Meeting> query, Constants.MeetingSortColumn column, bool ascending)
    {
        switch (column)
        {
            case Constants.MeetingSortColumn.MeetingType:
                return ascending
                    ? query.OrderBy(m => m.MeetingType.Description).ThenBy(m => m.MeetingDate).ThenBy(m => m.CompanyName)
                    : query.OrderByDescending(m => m.MeetingType.Description).ThenByDescending(m => m.MeetingDate).ThenByDescending(m => m.CompanyName);
        }
    }
like image 684
Tom Troughton Avatar asked Nov 10 '22 13:11

Tom Troughton


1 Answers

There are many reasons why this can happen, but from your sample the most probable is due to the fact that underlying database decides this. I presume that your sortedMeetings is still an IQueryable and thus the query is still being constructed. As your're including additional columns and calling ToList() different queries are being done to you db engine, and it may decide to use another index, or just another path for you query. If you're using Sql Server, profile your query and see the execution plan, nevertheless use an order by in what you want, it is you only assurance.

But present the sortedMeetings with the OrderBy for complete analysis.

EDIT:

Also, it seems that the origin IQueryable is not the same: temp2 derived drom sortedMeetings, temp4 and temp8 from temp. Also, if you're using EF6, use context.Database.Log to dump your queries, otherwise use a database profiler. Post the database queries here and we help you analyse it.

like image 65
saamorim Avatar answered Nov 14 '22 22:11

saamorim