在OData(v4) Web API c#中添加自定义分页
本文关键字:添加 自定义 分页 API Web OData v4 | 更新日期: 2023-09-27 18:15:57
我想知道是否有人能帮助我。我正在尝试实现自定义分页到OData提要(OData v4)。我正在从一个存储过程中填充IEnumerable,我在下面添加了分页方法(Working Perfect)
SELECT *
FROM (
SELECT ROW_NUMBER() OVER ( ORDER BY OrderID ) AS RowNum, *
FROM dbo.Order
WHERE CompanyID = @CompanyID
) AS RowConstrainedResult
WHERE RowNum >= @Start AND RowNum <= @Finish
ORDER BY RowNum
然而,我遇到的问题是,下面的代码工作完美,除了分页不工作
[EnableQuery]
public async Task<PageResult<Order>> GetOrders(ODataQueryOptions<Order> queryOptions)
{
int CompanyID = User.Identity.GetCompanyID().TryParseInt(0);
ODataQuerySettings settings = new ODataQuerySettings()
{
PageSize = 100,
};
int OrderCount = _OrderRepo.GetOrderCount(CompanyID);
int Skip = 0;
if (queryOptions.Skip != null)
{
Skip = queryOptions.Skip.Value;
}
IEnumerable<Order> results = await _OrderRepo.GetAll(CompanyID, Skip, 100);
IQueryable result = queryOptions.ApplyTo(results.AsQueryable(), settings);
Uri uri = Request.ODataProperties().NextLink;
Request.ODataProperties().TotalCount = OrderCount;
PageResult<Order> response = new PageResult<Order>(
result as IEnumerable<Order>,
uri, Request.ODataProperties().TotalCount);
return response;
}
基本上,我试图通过100批的结果页,只在需要时从数据库中取出100。
当我第一次调用控制器时,我得到了预期的结果。
http://localhost:24600/Data/Orders
但是当我查询这个nextLink(下面)时,我没有得到任何错误,但没有结果,尽管数据库中有超过50,000个结果,并且IEnumerable结果已正确更新。
http://localhost:24600/Data/Orders?$skip=100
如果有人帮我解决这个问题,我将非常感激,因为我是第一次使用odata。
更新看起来,它正在计算第一批的大小并将其作为总大小,尽管我设置了总大小。
我认为EnableQuery属性是问题所在。这似乎告诉框架你想让它处理一些事情。我下面的例子,sans attribute,是在asp.net core上使用odata(我认为唯一真正的区别是使用odatature而不是ODataProperties)…
public class ThingController : ODataController
{
[HttpGet]
public PageResult<Thing> GetThings(ODataQueryOptions<Thing> queryOptions)
{
var thingsToSkip = queryOptions?.Skip?.Value ?? 0;
var pageSize = 10;
var totalThings = GetThingCount();
var pageOfThings = GetThings(thingsToSkip, pageSize);
var showNextLink = thingsToSkip + pageOfItems.Count < totalThings;
return new PageResult<Things>(pageOfThings,
showNextLink ? Request.GetNextPageLink(pageSize) : null,
totalThings);
}
private int GetThingCount()
{
return 21;
}
private List<Things> GetThings(int skip, int take)
{
return Enumerable.Range(0, TotalThingCount())
.Select(r => new Thing { Id = r.ToString() })
.Skip(skip)
.Take(take)
.ToList();
}
您可以只返回完整的集合(如IQueryable
),并让OData处理分页:
[EnableQuery(PageSize = 100)]
public IQueryable<Order> Get()
{
return _OrderRepo.GetAll(CompanyID); //Assuming this returns an IQueryable
}
OData知道如何处理IQueryable
,并将使用.Top()
和.Skip()
来获取条目,这将由您的可查询提供者转换为SQL。(大概EF ?)