使用OrderBy的Linq查询分页

7
我希望能够返回一个特定实体按某个属性分组的列表,并按时间戳降序排列并进行分页(使用Skip和Take)。我的代码如下:
container.CoinMessageSet.Where(
                c => c.MessageState != MessageStateType.Closed &&
                     (c.DonorOperator.OperatorCode.Equals("opcode") ||
                      c.RecipientOperator.OperatorCode.Equals("opcode"))
                ).OrderByDescending(c => c.TimeStamp)
                 .GroupBy(c => c.Reference).Skip(x).Take(100);

执行时我收到了异常:

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

我调用了OrderBy()(虽然是倒序排列),而且在调用Skip()之前也调用了它!我错过了什么?

2个回答

7

您还没有对组进行排序;在分页之前,您需要这样做。例如:

.GroupBy(c => c.Reference).OrderBy(grp => grp.Key).Skip(x).Take(100);

(如果您想要反向排序组,也可以使用 OrderByDescending)

另外:由于您正在进行分组,原始数据中的顺序基本上是没有意义的;您可能可以删除 OrderByDescending(c => c.TimeStamp)

因此,最终结果如下:

var query = container.CoinMessageSet.Where(
            c => c.MessageState != MessageStateType.Closed &&
                 (c.DonorOperator.OperatorCode.Equals("opcode") ||
                  c.RecipientOperator.OperatorCode.Equals("opcode"))
            ).GroupBy(c => c.Reference).OrderBy(grp => grp.Key)
             .Skip(x).Take(100);

或者可能是:
var query = (from c in container.CoinMessageSet
             where c.MessageState != MessageStateType.Closed &&
                  (c.DonorOperator.OperatorCode == "opcode" ||
                   c.RecipientOperator.OperatorCode == "opcode")
             group c by c.Reference into grp
             orderby grp.Key
             select grp).Skip(x).Take(100);

感谢您对原问题的澄清,并意识到我有一个新问题 ;) (即“我必须按 TimeStamp 排序,但由于 GroupBy,这基本上是无用的”) - HTBR

2
很可能是因为在OrderByDescending之后使用了GroupBy。我认为你可以尝试:
container.CoinMessageSet.Where(
                c => c.MessageState != MessageStateType.Closed &&
                     (c.DonorOperator.OperatorCode.Equals("opcode") ||
                      c.RecipientOperator.OperatorCode.Equals("opcode"))
                ).OrderByDescending(c => c.TimeStamp)
                 .GroupBy(c => c.Reference).OrderByDescending(c = > c.Key).Skip(x).Take(100);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接