即使使用$ top,也强制订购OData项目

Bra*_*s83 1 linq entity-framework iqueryable odata asp.net-web-api

我有一个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();
}
Run Code Online (Sandbox Code Playgroud)

当用户将"$ top"放入查询字符串时,订单会全部搞乱(这可能会强制排序由主键完成,以获得一致的分页结果 - 但是,在我的情况下,这是相反的效果,它阻止我有一致的分页结果).

我已经尝试过移动.AsQueryable()到查询的早期(在.OrderBy(...)子句之前),我已经尝试过没有了.AsQueryable(),我已经尝试了两个AsQueryables等.

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

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

1.)我可以做些什么来使我的Order财产订购这里的默认行为?

2.)或者失败了,无论如何,是否有人欺骗WebApi/OData认为自定义了"$ orderby = Order"子句?

Dan*_*ira 5

要覆盖默认的排序顺序,你需要EnableQueryAttribute财产EnsureStableOrdering设置为false,像形容这里:

true值表示必要时应修改原始查询以保证稳定的排序顺序.false值表示可以在不修改查询的情况下将排序顺序视为稳定.确保稳定排序顺序的查询提供程序应将此值设置为false.默认值是true.

因此,在您的代码中,更改action属性,如下所示:

// GET api/documents
[EnableQuery(EnsureStableOrdering = false)]
public IQueryable<Item> Get()
{
    return ctx.Items.OrderBy(o => o.Order).AsQueryable();
}
Run Code Online (Sandbox Code Playgroud)