即使使用$ top,也会强制执行OData项目的排序

时间:2015-06-13 03:41:11

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

我有一个DbSet<Items>集合。

主键是Guid。我不想通过这个主键订购。我想通过名为&#34; Order&#34;。

的可编辑十进制属性进行排序

我所拥有的代码非常简单,并且在用户输入&#34; $ top&#34;参数进入请求:

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

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

当用户放置&#34; $ top&#34;在查询字符串中,顺序变得混乱(它可能会强制排序由主键完成,以获得一致的分页结果 - 但是,在我的情况下,这会产生相反的效果,它会阻止我从一致的分页结果)。

我已经尝试将.AsQueryable()移到查询的前面(.OrderBy(...)子句之前),我已经尝试了.AsQueryable(),而我是;用两个AsQueryables等尝试过它。

此表中将有 lot 项目,因此需要通过IQueryable完成(通过{{1枚举Web服务器上的所有项目)这里不是一个选项)。

到目前为止唯一有效的方法是传递&#34; $ orderby = Order&#34;来自客户,但我不想强迫(似乎很容易忘记)。

1。)我可以做些什么来使IEnumerable属性的排序成为默认行为吗?

2。)或者失败了,无论如何,无论如何都要欺骗WebApi / OData认为自定义&#34; $ orderby = Order&#34;条款被指定了吗?

2 个答案:

答案 0 :(得分:5)

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

  

true值表示原始查询应在何时修改   必须保证稳定的排序顺序。假值表示   无需修改查询即可将排序顺序视为稳定。   确保稳定排序顺序的查询提供程序应设置此值   为假。默认值为true。

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

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

答案 1 :(得分:1)

您可以手动调用控制器中的odata。这应该创建正确的排序IQueryable然后应用$ top和任何其他odata,如$ filter和$ skip。现在你不必返回导致问题的IQueryable,因为实际的查询是在管道中稍后执行的。

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

    public IEnumerable<Item> Get(ODataQueryOptions<Item> odata)
    {
        var collection = ctx.Items.OrderBy(o => o.Order);

        if (odata == null)
        {
            //return a default max size of 100
            return collection.Take(100).ToList();
        }

        var results = odata.ApplyTo(collection.AsQueryable()) as List<Item>;

        //still provide a max incase the $top wasn't specified.
        //you could check the odata to see if $top is there or not.
        return results.Take(100);
    }
}

更多信息可在WebApi documentation

中找到