I have a scenario where one Student (identified by StudentId) has many Courses. Each Course has StudentId(FK) and a Grade (simple text type). I want to build an IQueryable to pull 10 StudentIds (skipping first 5) by Course first Grade when sorted in descending order.
Tried below query but getting System.InvalidOperationException : The LINQ expression cannot be translated
var studentQuery= context.Set<Student>().AsNoTracking().Where(x=>x.IsActive);
var courseQuery= context.Set<Course>().AsNoTracking()
.OrderByDescending(x => x.Grade)
.GroupBy(x => x.StudentId)
.SelectMany(x => x.Select((b, i) => new { b, rn = i + 1 }))
.Where(x => x.rn == 1).Select(x => x.b);
return studentQuery.Join
(
courseQuery,
x => x.StudentId,
y => y.StudentId,
(a, b) => b
)
.Skip(5)
.Take(10)
.Select(x => x.StudentId);
I was able to resolve the issue using the query below. Used GroupJoin (instead Join) to handle "students without any courses" use case. When a course has no Grade, used null coalescing operator to fix that. Such students will be last in the pagination. I was surprised that Max worked on text/string data type. Although this is working am sure there is a better way to fix this.
Generated postgres SQL looks like