【问题标题】:Entity SQL Sort Then LINQ to Entities GroupBy Doesn't Return IOrderedQueryable实体 SQL 排序然后 LINQ 到实体 GroupBy 不返回 IOrderedQueryable
【发布时间】:2012-03-12 15:37:47
【问题描述】:

工作:我的 UI 将 jqGrid 中的 entity sql 排序表达式发送到我的 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:“Skip”方法仅支持 LINQ to Entities 中的排序输入。方法“OrderBy”必须在方法“Skip”之前调用。

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

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

【问题讨论】:

    标签: entity-framework-4 linq-to-entities query-builder entity-sql


    【解决方案1】:

    GroupBy() 返回一个IGrouping&lt;int, Worksheet&gt;。实际对象是一个ObjectQuery,返回为IQueryable。你链接到我的问题(ObjectQuery 什么时候真的是 IOrderedQueryable?),所以你知道这个 ObjectQuery 也实现了 IOrderedQueryable 的事实并不一定意味着它实际上是这样的。

    more elementary, related, question 中,Jon Skeet 区分了实际类型和编译时类型。重要的是编译时类型 (IQueryable)。

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

    【讨论】:

    • 谢谢!但这意味着它不能使用 esql 来完成,因为它必须在根据 Diego Vega 对实体进行任何 linq 之前发生......对吗?
    • 我认为你应该能够在你的例子中做qryGrouped.OrderBy()
    • 是的,我可以使用 OrderBy() linq 实体,但不能使用实体查询生成器。查询生成器的方法是 .OrderBy("it.WorksheetID DESC") 但它仅可从 ObjectQuery 获得,并且一旦它通过 linq2entities 变为 IQueryable 后,您将无法转换回 ObjectQuery 以使用此方法。我不想接受我唯一的选择是在实体 sql 中编写整个查询,包括 group by 子句......但我认为这是底线.. :-\
    • 恐怕,是的。但是你可以使用限制和跳过,不是吗?在 OrderBy (esql) 之后,就是。
    • 一开始我以为我可以,但后来我想,在分组之前应用分页没有多大意义……然后我会限制分组的结果集,这将返回不完整的结果..
    猜你喜欢
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    相关资源
    最近更新 更多