何时指定 PagingInfo.PagingCookie 和 PagingInfo.PageNumber

When to specify PagingInfo.PagingCookie and PagingInfo.PageNumber

虽然在网上阅读了大量可用资源,但我找不到一个明确的解释:

什么情况下PageingInfo.PageNumberPageingInfo.PagingCookie的值都需要赋值?

例如:假设我们有 10,000 条唯一记录,我们想检索所有这些记录,但一次检索 200 条记录。 我们是否必须迭代 PageNumber(50 次迭代),还是仅使用 PagingCookie 就足够了?

现在,我想分享一下我在网上找到的资源:

首先,许多在线资源链接到官方 MSDN 示例(对于 FetchXML:1, 2, for QueryExpression: 1, 2),但没有针对此问题的直接答案。他们都遍历 PageNumber,但据我了解(这可能是错误的),页面 always 有 5000 条记录(或者是吗?)。

其次,我发现 this 使用 PagingCookie 的演示,从 40 条记录中获取 6-10 条记录:

<fetch mapping="logical" count="5" page="2" paging-cookie="&lt;cookie page=&quot;1&quot;&gt;&lt;new_parentrecordid last=&quot;{F8DAB1AA-3A0F-E411-8189-005056B20097}&quot; first=&quot;{F8DAB1AA-3A0F-E411-8189-005056B20097}&quot; /&gt;&lt;/cookie&gt;" version="1.0">
    <entity name="new_parentrecord">
        <attribute name="new_name" />
        <link-entity name="new_childrecord" from="new_parentaid" to="new_parentrecordid">
            <attribute name="new_childrecordid" />
            <attribute name="new_name" />
        </link-entity>
    </entity>
</fetch>

然后,上面解释为下面的SQL查询:

select top 6 "new_parentrecord0".new_name as "new_name"
            , "new_parentrecord0".new_parentrecordId as "new_parentrecordid"
            , "new_childrecord1".new_childrecordId as "new_childrecord1.new_childrecordid"
            , "new_childrecord1".new_name as "new_childrecord1.new_name" 
from
     new_parentrecord as "new_parentrecord0" 
    join new_childrecord as "new_childrecord1" on ("new_parentrecord0".new_parentrecordId  =  "new_childrecord1".new_ParentAId) 
where
     ((("new_parentrecord0".new_parentrecordId > '01DBB1AA-3A0F-E411-8189-005056B20097'))) 
order by
     "new_parentrecord0".new_parentrecordId asc

因此,正如我在这个例子中看到的那样,不需要使用页码,因为在结果 SQL 查询中只使用了分页 cookie.

如果能对这个问题进行很好的澄清,那就太好了。

我的经验和我刚刚所做的额外研究表明,是的,我们确实需要遍历所有页面。虽然页码永远不会进入 SQL 查询,但它控制着哪个 ID SQL 将在其过滤器中使用。

查询中没有页号:

分页 cookie 中的 ID 保持不变:

页数:

ID的变化:

同样值得注意的是,如果您在不更改分页 cookie 中的页面或 ID 的情况下前进页面 #,

系统使用分页 cookie 的最后一个 ID 并扩展 SQL "top" 参数以获取您请求的页面数:

并且它必须对 SQL 记录集进行一些处理,因为它 returns 正确的记录数(在本例中为 20),ID 为高级:

PagingCookie 是服务器已传送给客户端的结果集的只读标识符。其目的是优化数据检索,不应修改。 PagingCookie 基本上告诉服务器可以大致找到指定页面的开始和结束位置。

我假设它使 CRM 服务器能够使用缓存的查询结果集。当使用分页 cookie 对结果集进行分页时,我注意到服务器只提交一次 SQL 查询(即当它收到没有分页 cookie 的查询时)并尽可能从内存中传递后续页面。

客户端在检索同一结果集的另一页时,只需将 cookie 复制到 FetchXMLQueryExpression 中即可。

据我所知(在 Dynamics CRM 2016 (V8.2) 上测试它也适用于连接。

我怀疑您显示的 SQL 查询实际上是篡改 PagingCookie 的结果:服务器无法在其缓存中找到该 cookie,假定原始结果集已被刷新,并且当它构建一个fresh SQL 查询它完全依赖于 cookie 声明的边界的正确性。因此出现了意想不到的 where 子句。

结论

始终使用 page 属性 (FetchXML) 或 PageInfo.PageNumber 属性 (QueryExpression)。不要修改 PagingCookie,只需将其复制到后续页面请求中即可。

未指定页面大小(count 属性)时,默认为最多 5,000 行。当预期的结果集大于该值时,需要迭代所有可用页面。

当您使用 Dynamics CRM On Premise 时,您可以使用 PowerShell 命令修改最大页面大小。