Pregunta

Works: My UI sends up entity sql sort expressions from a jqGrid to my DAL and then applies some Where clauses that get returned to my service layer. My service layer will then create a PaginatedList object that applies the Skip()..Take() to the IQueryable. Example:

var qry = ((IObjectContextAdapter)DbContext).ObjectContext
.CreateQuery<TEntity>(entityName)
.OrderBy(pEntitySQLSort.GetEntitySQL()); 
//GetEntitySQL() i.e. "it.WorksheetID ASC"
return qry.Where(p=> pStatus == "blah").Skip(5).Take(10);

Doesn't Work: Applying a GroupBy() then Select() that returns a list of the same type of entities (Worksheet). Example:

var qry = ((IObjectContextAdapter)DbContext).ObjectContext
.CreateQuery<TEntity>(entityName)
.OrderBy(pEntitySQLSort.GetEntitySQL());

var qryGrouped = qry.GroupBy(pWorksheet => pWorksheet.ParticipantID)
.Select(pGroup => new {Group = pGroup, LatestWorksheetID = pGroup.Max(pWorksheet => pWorksheet.WorksheetID)})
.Select(p => p.Group.FirstOrDefault(pWorksheet => pWorksheet.WorksheetID == p.LatestWorksheetID)); 

return qryGrouped.Skip(5).Take(10); //throws exception.

Throws NotSupportedException: The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.

It seems to me that the first snippet does return an IOrderedQueryable that applies the esql sorting expression but the second snippet does not? Or maybe does GroupBy() remove the ordering of a query/collection ? If this is is the case, and since esql must be applied BEFORE LINQ to Entities, how could I accomplish the sql sorting + LINQ GroupBy ?

Related:
When is ObjectQuery really an IOrderedQueryable?
Why can't we mix ESQL and LINQ TO Entities

¿Fue útil?

Solución

GroupBy() returns an IGrouping<int, Worksheet>. The actual object is an ObjectQuery returned as IQueryable. You linked to my question (When is ObjectQuery really an IOrderedQueryable?), so you know that the fact that this ObjectQuery also implements IOrderedQueryable does not necessarily mean that it actually behaves as such.

In a more elementary, related, question, Jon Skeet made the distinction between actual type and compile-time type. The compile-time type (IQueryable) is what matters.

So, GroupBy effectively cancels the previous OrderBy. In a quick test on a similar case I could see that even the ordering is gone in the grouping. Conclusion: you'll have to re-apply an OrderBy for the Skip to be executed successfully.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top