首页 > 其他分享 >Dynamics CRM 365 使用 FetchXml 分页(Page results using FetchXml)

Dynamics CRM 365 使用 FetchXml 分页(Page results using FetchXml)

时间:2024-06-17 09:55:39浏览次数:10  
标签:分页 记录 results paging FetchXml cookie fetchXml using 页面

介绍

可以通过设置页面大小来指定对每个请求检索的行数的限制。通过使用分页,您可以检索连续的数据页,这些数据页表示符合查询条件的所有记录。

默认和最大页面大小为5,000行。如果不设置页面大小,Dataverse将一次返回多达5000行数据。要获得更多行,必须发送额外的请求。

不要将fetch元素top属性与分页一起使用。这些限制查询结果的不同方法是不兼容的。
排序在获得一致的分页结果方面起着重要作用。

分页模式

简单模式

  • 只使用fetch元素计数和页面属性
  • 只适用于小数据集
  • 不能返回大于50,000条记录的数据集
  • 性能随着行数的增加而降低

在发送请求之前,可以通过将fetch元素page属性设置为1并将count属性设置为页面大小来请求第一页:

<fetch count='3' page='1'>
  <entity name='account'>
    <attribute name='name' />
    <order attribute='name' />
    <order attribute='accountid' />
  </entity>
</fetch>

要获得接下来的三条记录,增加页面值并发送另一个请求。

<fetch count='3' page='2'>
  <entity name='account'>
    <attribute name='name' />
    <order attribute='name' />
    <order attribute='accountid' />    
  </entity>
</fetch>

使用简单的分页(有时称为遗留分页),Dataverse检索到当前页面的所有查询结果,选择该页所需的记录数量,然后忽略其余的记录。这允许通过数据快速向后和向前分页或跳转到特定页面。但是,记录的总数被限制为50,000,并且对于复杂查询和任意排序的不同查询结果可能存在性能问题。

简单的分页对于小数据集效果很好,但是随着数据集中的行数增加,性能会受到影响。使用简单分页可以检索的行总数为50,000行。为了在所有情况下获得最佳性能,建议始终使用分页cookie。

分页cookies模式

  • 使用fetch元素countpagepaging-cookie属性
  • paging-cookie属性值设置为上一页返回的值
  • 推荐用于所有数据集大小
  • 有些查询不允许对cookie进行分页

以下示例代码将会通过分页方式返回所有满足条件的数据

        static void Main(string[] args)
        {
            CrmServiceClient service = new CrmServiceClient(ConfigurationManager.ConnectionStrings["CRMConnString"].ConnectionString);
            string fetchXml = @"<fetch>
                                    <entity name='account'>
                                        <attribute name='name' />
                                        <attribute name='createdon' />
                                        <attribute name='address1_city' />
                                        <attribute name='numberofemployees' />
                                        <order attribute='createdon' descending='false' />
                                    </entity>
                                </fetch>";
            OutputFetchRequestClass.OutputFetchRequest(service, fetchXml);
            EntityCollection entityCollection = RetrieveMultipleAll(service, fetchXml);

            Console.WriteLine();
            Console.ReadKey();
        }
        public static EntityCollection RetrieveMultipleAll(IOrganizationService service, string fetchXml)
        {
            string pagingCookie = null;
            int pageNumber = 1;
            EntityCollection entityCollectionAll = new EntityCollection();
            while (true)
            {
                var xmlQuery = CreateXml(fetchXml, pagingCookie, pageNumber, 3);

                var request = new RetrieveMultipleRequest()
                {
                    Query = new FetchExpression(fetchXml)
                };

                var response = (RetrieveMultipleResponse)service.Execute(request);

                var entityCollection = response.EntityCollection;

                entityCollectionAll.Entities.AddRange(entityCollection.Entities);
                entityCollection.Entities.Clear();

                if (entityCollection.MoreRecords)
                {
                    // Increment the page number to retrieve the next page.
                    pageNumber++;
                    // Set the paging cookie to the paging cookie returned from current results.
                    pagingCookie = entityCollection.PagingCookie;
                }
                else
                {
                    // If no more records are in the result nodes, exit the loop.
                    break;
                }
            }
            return entityCollectionAll;
        }

        private static string CreateXml(string fetchXml, string pagingCookie = null, int pageNumber = 1, int fetchCount = 5000)
        {
            XElement fetchNode = XElement.Parse(fetchXml);

            //Set the page
            fetchNode.SetAttributeValue("page", pageNumber);

            // Set the page size
            fetchNode.SetAttributeValue("count", fetchCount);

            if (pagingCookie != null)
            {
                // Set the fetch paging-cookie attribute with the paging cookie from the previous query
                fetchNode.SetAttributeValue("paging-cookie", pagingCookie);
            }
            return fetchNode.ToString();
        }

排序

在分页数据时,页面的排序方式有很大不同。如果有关结果排序方式的信息不明确,则 Dataverse 无法一致或有效地返回分页数据。

指定查询的顺序。使用 FetchXml,如果未向查询添加任何 order 元素,Dataverse 将根据表的主键添加 order。但是,QueryExpression 不会,并且当您的查询指定 distinct 结果时,不会返回主键值,因此 Dataverse 无法添加此默认顺序。必须指定分页排序。如果不指定任何顺序, distinct 则查询结果可能会以随机顺序返回。OData 不提供任何返回不同结果的选项,但在检索分页结果时仍应应用顺序。

分页是动态的。每个请求在收到时都会独立评估。paging-cookie 告诉 Dataverse 上一页。使用此paging-cookie数据,Dataverse 可以从上一页上一条记录之后的下一条记录开始。

分页在向前运行时效果最好。如果返回并检索之前检索的页面,结果可能会有所不同,因为自上次检索页面以来,可能会添加、删除或修改记录。换句话说,如果你的页面大小是 50 并且你返回,你会得到 50 条记录,但它们可能不是相同的 50 条记录。如果在数据集的页面中不断前进,则可以预期所有记录都以一致的顺序返回。

确定性排序意味着有一种方法可以一致地计算顺序。对于一组给定的记录,这些记录始终以相同的顺序返回。如果需要一致的顺序和分页,则必须包含一些唯一值或列值的组合,并指定要计算它们的顺序。

标签:分页,记录,results,paging,FetchXml,cookie,fetchXml,using,页面
From: https://www.cnblogs.com/YuYangBlogs/p/18247915

相关文章