[英]OData causes wrong ordering in ASP.NET Web API
I'm using OData with ASP.NET Web API because I want to take advantage of its $skip option by using it for paging on the client.我将 OData 与 ASP.NET Web API 一起使用,因为我想通过使用它在客户端上进行分页来利用它的 $skip 选项。 However, I face an issue and I'm not sure whether it is a bug or I'm doing something wrong.但是,我遇到了一个问题,我不确定这是一个错误还是我做错了什么。
I have the following method:我有以下方法:
[HttpGet]
[Route("api/people")]
[EnableQuery(PageSize = 10, AllowedQueryOptions = AllowedQueryOptions.Skip)]
public IHttpActionResult GetAll()
{
// Declare a simple list of Person objects.
// Every Person object has only 3 properties - Id, Name and DateCreated.
var peopleList = new List<Person>();
for (int i = 0; i < 50; i++)
{
// Create the list with example Person objects.
// Start from new Person() { Id = 1, Name = "Person #1", DateCreated = Tomorrow.
// Continue with Person() { Id = 2, Name = "Person #2", DateCreated = The Day After Tomorrow.
// Do this till i == 50.
peopleList.Add(new Person()
{
Id = (i + 1),
Name = "Person #" + (i + 1),
DateCreated = DateTime.Now.AddDays(i)
});
}
// Get only those Person objects the Ids of which are prime numbers.
// Order the list by the most recently added, meaning the one that has a most recent DateCreated value.
var outputList = peopleList
.Where(p => p.Id % 2 == 0)
.OrderByDescending(p => p.DateCreated)
.ToList();
// Return the list from the method.
return Ok(outputList);
}
So, written this way I expect that if I make a request to "api/people", I will get the 10 most recent (because of the PageSize = 10 option written in the EnableQuery attribute) People objects with prime Ids.因此,以这种方式编写,我希望如果我向“api/people”发出请求,我将获得 10 个最近的(因为在 EnableQuery 属性中写入的 PageSize = 10 选项)具有主要 Id 的 People 对象。 However, the result that I get is:但是,我得到的结果是:
[
{
"id": 2,
"name": "Person #2",
"dateCreated": "2015-11-06T10:48:09.1224206+02:00"
},
{
"id": 4,
"name": "Person #4",
"dateCreated": "2015-11-08T10:48:09.1224206+02:00"
},
...
{
"id": 20,
"name": "Person #20",
"dateCreated": "2015-11-24T10:48:09.1224206+02:00"
}
]
If I exclude this line如果我排除这一行
[EnableQuery(PageSize = 10, AllowedQueryOptions = AllowedQueryOptions.Skip)]
I get the correct ordering but of course I'm getting the whole set of 50 Person objects, not just 10 as I want.我得到了正确的排序,但当然我得到了整套 50 个 Person 对象,而不仅仅是我想要的 10 个。
[
{
"id": 50,
"name": "Person #50",
"dateCreated": "2015-12-24T10:56:55.7456064+02:00"
},
{
"id": 48,
"name": "Person #48",
"dateCreated": "2015-12-22T10:56:55.7456064+02:00"
},
...
{
"id": 2,
"name": "Person #2",
"dateCreated": "2015-11-06T10:48:09.1224206+02:00"
}
]
I don't want to let the client order the list, the only thing that I want is to ensure that the maximum size of the returned collection is 10 objects and that the client can specify the number of objects to be skipped (using the $skip option).我不想让客户端对列表进行排序,我唯一想要的是确保返回集合的最大大小为 10 个对象,并且客户端可以指定要跳过的对象数(使用 $跳过选项)。
So, why is this thing happening like that and how can I fix it?那么,为什么会发生这样的事情,我该如何解决?
Okay, I found the solution here .好的,我在这里找到了解决方案。 It seems like I have to add EnableStableOrdering = false to my EnableQuery attribute like this:似乎我必须像这样将 EnableStableOrdering = false 添加到我的 EnableQuery 属性中:
Solution:解决方案:
[EnableQuery(PageSize = 10, AllowedQueryOptions = AllowedQueryOptions.Skip, EnsureStableOrdering = false)]
Here's what EnableStableOrdering really does (got from source code):下面是 EnableStableOrdering 的真正作用(从源代码中得到):
Summary:概括:
Gets or sets a value indicating whether query composition should alter the original query when necessary to ensure a stable sort order.获取或设置一个值,该值指示查询组合是否应在必要时更改原始查询以确保稳定的排序顺序。
Returns:返回:
A true value indicates the original query should be modified when necessary to guarantee a stable sort order. true 值表示在必要时应修改原始查询以保证稳定的排序顺序。 A false value indicates the sort order can be considered stable without modifying the query. false 值表示无需修改查询即可认为排序顺序是稳定的。 Query providers that ensure a stable sort order should set this value to false.确保稳定排序顺序的查询提供程序应将此值设置为 false。 The default value is true.默认值是true。
As the default value of this option is true , I just had to set it to false .由于此选项的默认值为true ,我只需将其设置为false 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.