【问题标题】:Linq Limiting records gives error for paging?Linq 限制记录给出分页错误?
【发布时间】:2015-01-27 20:13:45
【问题描述】:

我想创建分页,我的 LINQ 查询出错:

var query = from c in db.Projects.Take(2).Skip(2) orderby c.ProjectId descending select c;

给出以下错误:

$exception  {"The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'."} System.Exception {System.NotSupportedException}

【问题讨论】:

  • 方法'OrderBy'必须被调用之前方法'Skip'应该是显而易见的
  • 不是每个人都能阅读。许多拒绝阅读的人仍在尝试编程。

标签: c# asp.net-mvc linq entity-framework asp.net-mvc-5


【解决方案1】:

试试:

var query = (from c in db.Projects orderby c.ProjectId descending select c).AsEnumerable().Skip(2).Take(2)

或者更高效(归功于 Jon Skeet)

var query = (from c in db.Projects orderby c.ProjectId descending select c).Skip(2).Take(2)

【讨论】:

  • 在这里使用 AsEnumerable 意味着不会在数据库中执行分页 - 所以如果 OP 实际上 要求记录 1,000,000 到 1,000,009,它将获取最初的一百万条记录,只是为了把它们扔掉。
  • @JonSkeet 同意了。但是,有没有办法在没有这种开销的情况下实际执行使用 linq-to-sql 查询?
  • 是的 - 只需删除 AsEnumerable 调用。
  • @JonSkeet 非常正确。谢谢。
【解决方案2】:

该错误准确地描述了所需的内容 - 您的序列需要在跳过/采取任何意义之前进行排序。你已经知道你想要什么排序——你只需要在逻辑管道中比分页更早地实现它。此外,在这里使用查询表达式确实没有任何好处。我建议你使用:

var query = db.Projects
              .OrderByDescending(c => c.ProjectId)
              .Skip(2)
              .Take(2);

(如果你真的想要它可以全部放在一行中,但我发现如果它是垂直布局的,则更容易理解管道。)

请注意,我还颠倒了 SkipTake 的顺序 - 在您的示例代码中,您几乎永远不会希望 TakeSkip 之前...显示的Take(2).Skip(2) 永远不会返回任何结果...Take(2) 部分的结果是一个最多包含两个结果的序列,然后Skip(2) 跳过了前两个结果...什么也不留下。通常你有类似的东西:

.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2021-06-11
    • 2022-10-18
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多