Reputation: 1471
I have a scenario where I had to first group by and then sort each group. I came up with following working query :
applicants = context.Applicants
.OrderBy(app => app.Id).Skip((pageNumber - 1)*defaultPageSize)
.Take(defaultPageSize)
.GroupBy(app => app.PassportNumber)
.Select(g => g.OrderBy(d => d.IsEndorseChild)).ToList()
.SelectMany(grouping => grouping)
.ToList();
But this doesn't work :
applicants = context.Applicants
.OrderBy(app => app.Id).Skip((pageNumber - 1)*defaultPageSize)
.Take(defaultPageSize)
.GroupBy(app => app.PassportNumber)
.Select(g => g.OrderBy(d => d.IsEndorseChild))
.SelectMany(grouping => grouping)
.ToList();
First query produces result(these are the Id of the applicants returned) like:
7, 10, 8, 2, 9, 6, 5, 3, 4, 1
but second query produces:
7, 10, 8, 2, 9, 6, 3, 4, 5, 1
I am not sure why is this happening and what is the difference between the queries.
What exactly am I missing here ?
EDIT : Example Input and Expected Output :
Applicant 1 => ID : 1
IsEndorsed : 0
Passport : ABC123
Applicant 2 => ID : 2
IsEndorsed : 1
Passport : ABC123
Applicant 3 => ID : 3
IsEndorsed : 0
Passport : ABC1234
Applicant 4 => ID : 4
IsEndorsed : 0
Passport : A1234
Applicant 5 => ID : 5
IsEndorsed : 1
Passport : PQR123
Applicant 6 => ID : 6
IsEndorsed : 1
Passport : PQR123
Applicant 7 => ID : 7
IsEndorsed : 0
Passport : PQR123
Expected output : (Grp by Passport Number and in each group IsEndorsed = 0 is at top)
----------------------------------------------
Applicant 1 => ID : 1
IsEndorsed : 0
Passport : ABC123
Applicant 2 => ID : 2
IsEndorsed : 1
Passport : ABC123
Applicant 3 => ID : 3
IsEndorsed : 0
Passport : ABC1234
Applicant 4 => ID : 4
IsEndorsed : 0
Passport : AX1234
Applicant 7 => ID : 7
IsEndorsed : 0
Passport : PQR123
Applicant 5 => ID : 5
IsEndorsed : 1
Passport : PQR123
Applicant 6 => ID : 6
IsEndorsed : 1
Passport : PQR123
Upvotes: 3
Views: 403
Reputation: 174369
You are ordering by a boolean value. As soon as two of the values within one group have the same value of IsEndorseChild
their order relative to each other is generally undefined.
This OrderBy
is actually being translated to a SQL ORDER BY
and the result therefore also depends on the ORDER BY
implementation of the database you are using. It could either be stable or unstable.
Unstable means that it can return rows with the same ordered value in any order.
Stable means that it will return them in the same order as they were input.
SQL Server for example has an unstable sort: Is SQL order by clause guaranteed to be stable ( by Standards)
So, my conclusion is, that the ToList
call - the only difference in both of your queries - has no impact on the result. The difference is simply caused by the unstable sort.
Upvotes: 8