ASP.NET 5 WebAPI使用OData时如何获取分页信息及单条匹配记录
问题解答
问题1:Search方法返回分页统计信息
有两种常用实现方案:
- 原生OData方案:无需修改现有代码,只要请求接口时带上
$count=true查询参数,[EnableQuery]会自动在响应体的@odata.count字段返回总匹配记录数,前端可以根据每页条数自行计算总页数。如果需要统一限制每页条数,直接在[EnableQuery]特性上配置PageSize属性即可。 - 自定义封装响应结构:如果需要把分页统计信息和数据固定封装在一起返回,可以参考以下改造方案:
首先定义通用分页返回类:
public class PagedResult<T> { public List<T> Data { get; set; } public int TotalRecordsAvailable { get; set; } public int TotalPagesAvailable { get; set; } }
改造Search方法,手动处理OData查询规则:
[HttpGet] // 手动处理查询时需要去掉[EnableQuery]特性,避免重复应用规则 public PagedResult<Product> Search([FromQuery] ODataQueryOptions<Product> options) { // 忽略分页参数(Top/Skip),先计算所有匹配记录的总条数 var totalRecords = options.ApplyTo(_db.Products, ignoreQueryOptions: AllowedQueryOptions.Top | AllowedQueryOptions.Skip) .Cast<Product>() .Count(); // 应用所有OData查询规则(筛选、排序、分页等),获取当前页数据 var pageData = options.ApplyTo(_db.Products) .Cast<Product>() .ToList(); // 计算总页数,优先取请求的$top值,无配置时用默认值500 var pageSize = options.Top?.Value ?? 500; var totalPages = (int)Math.Ceiling(totalRecords / (double)pageSize); return new PagedResult<Product> { Data = pageData, TotalRecordsAvailable = totalRecords, TotalPagesAvailable = totalPages }; }
问题2:First方法应用OData筛选后再取第一条
同样通过注入ODataQueryOptions手动应用查询规则即可,注意要去掉原有的[EnableQuery]特性避免重复处理,同时给接口配置单独路由避免和Search方法的路由冲突:
[HttpGet("first")] public Product First([FromQuery] ODataQueryOptions<Product> options) { // 先应用所有OData查询规则(筛选、排序等)得到过滤后的查询对象 var filteredQuery = options.ApplyTo(_db.Products).Cast<Product>(); // 再取匹配的第一条记录 return filteredQuery.FirstOrDefault(); }
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

