在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。

更新

看起来,它正在计算第一批的大小并将其作为总大小,尽管我设置了总大小。

在OData(v4) Web API c#中添加自定义分页

我认为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 ?)