ASP.NET Core Web服务客户端与服务端驱动分页差异咨询
客户端驱动分页的问题解释
客户端驱动分页基于$skip+$top的偏移量逻辑,它的正常运行有个强前提:两次分页请求之间,数据集的排序规则、总条目数完全没有变化。一旦数据发生增删,偏移量的计算基准就会失效,原文描述的重复返回问题常见于两种场景:
- 排序规则不稳定
比如你仅按非唯一的「创建时间」「上架时间」字段排序,没有配置次级唯一排序规则(比如主键ID),数据库的排序结果会因为条目变更出现波动。举个实际例子:
- 第一页请求
GET ~/Products?$skip=0&$top=5,返回ID为101、102、103、104、105的记录- 翻下一页前ID为103的记录被删除
- 第二页请求
GET ~/Products?$skip=5&$top=5,因为排序不稳定,原本在第一页的105被排到了偏移量为5的位置,最终第二页返回105、106、107、108、109,105就被重复返回了。
- 用户来回翻页时前面的条目被删除
比如你看完第2页(skip=5&top=5)之后,第1页有2条记录被删除,你返回第1页的时候,原本第2页开头的2条记录会被前移到第1页,也会出现重复返回的情况。
你自己的测试没有复现问题,是因为你用了唯一主键作为排序字段,排序规则稳定,且删除的是当前页末尾和下一页开头的记录,只会触发条目前移,不会出现重复,但不代表这个问题不存在。
服务端驱动分页和客户端驱动分页的核心区别
服务端驱动分页是基于游标的分页逻辑,和偏移量分页的差异如下:
- 客户端驱动分页:每次请求都携带偏移量和每页数量,服务端不需要保存任何分页状态,每次都全量扫描数据集计算偏移量,数据变更时必然会出现偏移错位,适合数据不会频繁变更的静态列表场景。
- 服务端驱动分页:你第一次请求数据后,服务端返回当前页数据的同时,会返回携带
$skiptoken的下一页链接,这个token本质是当前页最后一条记录的排序字段值(比如按ID升序排序时,第一页最后一条ID是105,token就会记录ID>105的过滤规则)。你请求下一页时,服务端直接用token作为过滤条件取数,根本不关心前面有多少条数据被增删,永远返回上一页最后一条之后的内容,不会出现重复或者漏数据的问题,适合数据频繁变更的动态列表场景。
针对你当前的OData实现,只要你在OData配置中设置了PageSize参数,框架就会自动启用服务端分页,返回的响应中会自动生成带skiptoken的下一页链接,不需要你额外写分页逻辑。
内容的提问来源于stack exchange,提问作者JustLooking
相关产品推荐
相关产品推荐

