linq - 即使使用 $top 也强制执行 OData 项的排序

标签 linq entity-framework asp.net-web-api odata iqueryable

我有一个 DbSet<Items>收藏。

主键是一个 Guid。我不想按这个主键排序。我想通过名为“Order”的可编辑十进制属性进行排序。

我的代码非常简单,在用户将“$top”参数放入请求之前,它运行良好:

public class ItemsController : ApiController
{
    protected DbContext ctx = // ...

    // GET api/documents
    [EnableQuery()]
    public IQueryable<Item> Get()
{
    return ctx.Items.OrderBy(o => o.Order).AsQueryable();
}

当用户将 "$top"放入查询字符串时,顺序会变得一团糟(它可能强制排序由主键完成,以获得一致的分页结果——但是,在我的情况下,这是相反的效果,它阻止我获得一致的分页结果)。

我试过搬家.AsQueryable()为了在查询中更早(在 .OrderBy(...) 子句之前),我尝试过没有 .AsQueryable() ,我已经用两个 AsQueryables 等尝试过了。

这个表中会有很多项目,所以需要通过IQueryable来完成。 (通过 IEnumerable 枚举 Web 服务器上的所有项目在这里不是一个选项)。

到目前为止唯一有效的是从客户端传递“$orderby=Order”,但我不想强制它(似乎它很容易被遗忘)。

1.) 我能做些什么来通过我的 Order 订购吗?属性这里的默认行为?

2.) 或者失败了,无论如何要欺骗 WebApi/OData 认为指定了自定义的“$orderby=Order”子句?

最佳答案

要覆盖默认排序顺序,您需要将 EnableQueryAttribute 的属性EnsureStableOrdering 设置为false,例如describe here :

A true value indicates the original query should be modified when necessary to guarantee a stable sort order. A false value indicates the sort order can be considered stable without modifying the query. Query providers that ensure a stable sort order should set this value to false. The default value is true.



所以在你的代码中,像这样更改 action 属性:
// GET api/documents
[EnableQuery(EnsureStableOrdering = false)]
public IQueryable<Item> Get()
{
    return ctx.Items.OrderBy(o => o.Order).AsQueryable();
}

关于linq - 即使使用 $top 也强制执行 OData 项的排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30814824/

相关文章:

asp.net - 加载资源失败:服务器响应状态为401(未经授权)/App/AngularJS/angular.min.js

angularjs - 使用 WebAPI 对 ng-grid 进行服务器端分页+过滤+排序

asp.net - JSON.net linq无法使用where语句选择节点

c# - 使用与绑定(bind)不同的数据源将列动态添加到 Gridview

c# - 用于过滤表单集合的 Linq 表达式

c# - Microsoft Azure 中的 SQL 连接错误

wpf - 使用 WPF/Entity Framework 跨多个窗口进行数据绑定(bind)?是否传递上下文?

asp.net-mvc-4 - WebAPI 如何指定将到达 Controller 的路由

c# - 如何使用 LINQ 比较两个 IEnumerable 集合

c# - LINQ OrderBy 仅适用于第二个属性