1

作品:我的 UI 将实体 sql排序表达式从 jqGrid 发送到我的 DAL,然后应用一些返回到我的服务层的 Where 子句。然后,我的服务层将创建一个 PaginatedList 对象,该对象将 Skip()..Take() 应用于 IQueryable。例子:

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);

不起作用:应用 GroupBy() 然后 Select() 返回相同类型实体的列表(工作表)。例子:

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.

引发 NotSupportedException:仅 LINQ to Entities 中的排序输入支持方法“Skip”。必须在方法“Skip”之前调用方法“OrderBy”。

在我看来,第一个片段确实返回了一个应用 esql 排序表达式的 IOrderedQueryable,但第二个片段没有?或者 GroupBy() 是否删除了查询/集合的顺序?如果是这种情况,并且由于必须在 LINQ to Entities 之前应用 esql,我该如何完成 sql 排序 + LINQ GroupBy ?

相关:
ObjectQuery 何时真正成为 IOrderedQueryable?
为什么我们不能混合使用 ESQL 和 LINQ TO 实体

4

1 回答 1

1

GroupBy()返回一个IGrouping<int, Worksheet>. 实际对象是ObjectQuery返回为IQueryable. 您链接到我的问题(ObjectQuery 何时真的是 IOrderedQueryable?),所以您知道这ObjectQuery也实现了这一事实IOrderedQueryable并不一定意味着它实际上表现得如此。

在一个更基本、相关的问题中,Jon Skeet 区分了实际类型和编译时类型。编译时类型 ( IQueryable) 很重要。

所以,GroupBy有效地取消了之前的OrderBy. 在对类似案例的快速测试中,我可以看到即使排序在分组中也消失了。结论:您必须重新申请OrderBy才能Skip成功执行。

于 2012-03-12T20:38:10.087 回答