我有一个以零碎的方式构建的 LINQ 查询,如下所示:
var initialQuery = from item in MyContext where xxx == yyy select item;
var furtherQuery = from item in initialQuery where bla == foo select new { some stuff };
// more code here...
// eventually:
var yetAnotherQuery = (from item in furtherQuery ...)
.OrderBy(my_condition);
// As far as I know, the following query should still maintain the order of the previous one
// see: https://stackoverflow.com/questions/911942/are-subqueries-in-linqtosql-guaranteed-to-be-in-the-same-order-as-their-parent
var stillAnotherQuery = (from item in yetAnotherQuery
select item.data_I_care_about)
.Distinct();
// And finally...
var finalQuery = stillAnotherQuery.Skip(PageIndex).Take(PageSize);
但是当调用 Skip()
时出现异常,表示查询未排序!
显然我上面的代码注释和 referenced SO question 表明了什么并不完全正确。事实上another SO answer表示不保证该订单的保存。
有人知道实现我想要实现的目标的好方法吗?
我考虑过在中间结果中简单地包含一个 ROW_NUMBER
,并在最后按它进行排序,但我找不到在结果中获取该 ROW_NUMBER
的方法通过 LINQ。
我见过几个other所以questions试图 get the ROW_NUMBER在那里,但据我所知,它们都是客户端。
我似乎把自己描绘在一个角落里。 有人知道(LINQ 友好的)出路吗?
<小时/>更新
<小时/>有些人建议我在 OrderBy()
之前执行 Distinct()
。
我相信这会给我不同的结果。
假设我有这张数据表
myRank | myData
-------+--------
3 | A
1 | B
2 | A
假设我按myRank
排序,我关心的数据是myData
,想象一下我原来的代码是这样的:
var query = from item in MyTable
select item;
query = query.OrderBy(item => item.myRank);
var derivedQuery = from item in query // Note: we throw away myRank
select item.myData;
derivedQuery = derivedQuery.Distinct();
如果我交换 OrderBy()
和 Distinct()
的顺序,我会得到不同的结果。我不希望 myRank
包含在 Distinct()
中。
抱歉,这是一个更大流程的一部分,因此很难了解这个问题的所有细节。
但希望这是有道理的?
最佳答案
问题不在于元素不再排序。
问题在于 Distinct() 返回 IQueryable<T>
而 OrderBy() 返回 IOrderedQueryable<TSource>
,这显然是分页与 EF 一起工作所必需的
交换 Distinct() 和 OrderBy() 步骤应该可以解决问题
编辑
我建议大致如下:
var query = from item in MyTable
select item;
query = query.GroupBy(item => item.myData, item => item.myRank);
var derivedQuery = query.OrderBy(group => group.Min())
.Select(group.Key);
澄清:
- 无论如何,分组依据都会产生独特的键(myData)
- 按
myRank
的 Min() 排序每个组将实现与首先全局 myRank 排序(升序)相同的顺序,然后执行 Distinc()
关于LINQ - 如何保持(复杂)结果有序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7367666/