我想知道是否有人能够帮助我。我正在尝试实现自定义分页到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。
更新
看起来,它正在计算第一批的大小并将其作为总大小,即使我正在设置总大小。它似乎无法超越初始大小。
答案 0 :(得分:1)
您只需返回完整集(如IQueryable
)并让OData处理分页:
[EnableQuery(PageSize = 100)]
public IQueryable<Order> Get()
{
return _OrderRepo.GetAll(CompanyID); //Assuming this returns an IQueryable
}
OData知道如何处理IQueryable
并将使用.Top()
和.Skip()
来获取条目,这将由可查询提供程序转换为SQL。 (据推测EF?)
答案 1 :(得分:0)
我认为EnableQuery属性是问题所在。似乎这样告诉框架您希望它处理事情。下面的示例是sans属性,它是在asp.net核心上使用odata的(我认为唯一真正的区别是使用ODataFeature而不是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();
}