天天看点

使用Flow分页处理数据

我是微软Dynamics 365 & Power Platform方面的工程师/顾问罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面的微软最有价值专家(Microsoft MVP),欢迎关注我的微信公众号 MSFTDynamics365erLuoYong ,回复462或者20220131可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!

我们知道插件或者自定义工作流活动,现在新推出的​​Custom API​​都受到要在两分钟之内运行完毕的限制,且该限制无法更改。所以如果处理很多记录的时候要切割开来处理,否则可能碰到在开发环境因为数据量少没问题,到了生产环境数据量大不能在2分钟内处理完毕就会有问题。今天我来介绍下用Flow调用Custom API逐页处理数据的一种方法。

因为我前面的博文 ​​Dynamics 365的Custom API介绍​​ 对Custom API介绍的比较详细,所以我这里不会详细说如何创建Custom API,就指出一些需要注意的地方和参数。Custom API的Is Fuction记得要设置为No,因为据我所知,调用Function类型的Custom API没有那么简便,当然啦,我们这里是处理数据,也不应该用Function这种类型。

使用Flow分页处理数据

然后我新增了分页需要的三个输入参数如下:

使用Flow分页处理数据
使用Flow分页处理数据
使用Flow分页处理数据

也有一个输出参数如下:

使用Flow分页处理数据

然后Custom API我使用的代码如下:

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Xml.Linq;

namespace D365.Plugins
{
    public class CustomAPIHandleDataPagebyPage : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            //获取日志服务
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            //写一些日志,方便跟踪
            tracingService.Trace($"Enter CustomAPIHandleDataPagebyPage on {DateTime.UtcNow.ToString()}");
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService adminOrgSvc = serviceFactory.CreateOrganizationService(null);
            string pagingCookie = context.InputParameters["ly_pagingCookie"].ToString();
            int pageNumber = Convert.ToInt32(context.InputParameters["ly_pageNumber"].ToString());
            int recordsPerPage = Convert.ToInt32(context.InputParameters["ly_recordsPerPage"].ToString());
            tracingService.Trace($"pagingCookie={pagingCookie},pageNumber={pageNumber},recordsPerPage={recordsPerPage}");
            string nextPageCookie = string.Empty;
            string fetchXml = @"<fetch version='1.0' mapping='logical' distinct='false'>
  <entity name='ly_demosubentity'>
    <attribute name='ly_demosubentityid' />
    <attribute name='ly_decimalfield2' />
    <order attribute='ly_demosubentityid' descending='false' />
    <filter type='and'>
      <condition attribute='statecode' operator='eq' value='0' />
    </filter>
  </entity>=
</fetch>";

            string xml = CreateXml(fetchXml, pagingCookie, pageNumber, recordsPerPage);
            tracingService.Trace($"xml={xml}");
            RetrieveMultipleRequest retrieveRequest = new RetrieveMultipleRequest
            {
                Query = new FetchExpression(xml)
            };
            retrieveRequest.Parameters.Add("BypassCustomPluginExecution", true);
            EntityCollection entityCollection = ((RetrieveMultipleResponse)adminOrgSvc.Execute(retrieveRequest)).EntityCollection;
            if (entityCollection.MoreRecords)
            {
                nextPageCookie = entityCollection.PagingCookie;
            }
            foreach (var entity in entityCollection.Entities)
            {
                entity["ly_decimalfield2"] = (decimal)2022;
                adminOrgSvc.Update(entity);
            }
            context.OutputParameters["ly_nextPageCookie"] = nextPageCookie;
        }

        public string CreateXml(string xml, string cookie, int page, int count)
        {
            XDocument doc = XDocument.Parse(xml);
            if (!string.IsNullOrEmpty(cookie))
            {
                doc.Root.Add(new XAttribute("paging-cookie", cookie));
            }
            doc.Root.Add(new XAttribute("page", page));
            doc.Root.Add(new XAttribute("count", count));
            return doc.ToString(SaveOptions.DisableFormatting);
        }
    }
}      

然后我创建一个Flow来测试下:

使用Flow分页处理数据

Flow中我先声明两个变量如下:

使用Flow分页处理数据

因为要循环处理,所以这里我添加了一个Do Until,外层设置如下:

判断表达式左边用的是 empty(variables('PagingCookie')) 。

使用Flow分页处理数据

Do Until调用Microsoft Dataverse连接器的 Perform an unbound action,设置如下:

使用Flow分页处理数据

然后还要将Custom API传出的输出参数设置下,如下:

使用Flow分页处理数据

还有页码要增加1,设置如下:

使用Flow分页处理数据

总体如下:

使用Flow分页处理数据

继续阅读