如何使用FetchExpression和retrievemultiple来获取多页实体?

问题描述 投票:0回答:2

我想构建一个控制台应用程序,它可以获取 xml 查询并使用 Microsoft.Xrm.Sdk 对所有结果启动工作流程。

我使用 FetchExpression 将 xml 字符串解释为查询,并使用 RetireveMultiple 来获取结果。

不幸的是 RetrieveMultiple 似乎页面大小限制为 5000。

我在其他项目中使用 QueryExpression 解决了这个问题,设置其 PagingInfo 并循环直到没有更多记录,但 FetchExpression 似乎没有此分页选项。

任何人都可以提出一个解决方案来解决这个问题吗?或者是否有另一种方法可以跨 1000 条记录运行工作流程,而无需在 UI 中对所有记录进行分页?

using System;
using System.Configuration;
using System.Linq;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Tooling.Connector;

class Program
{
    static void Main(string[] args)
    {
        const string WORKFLOW_NAME = "Do the thing";

        const string FETCH_XML_QUERY = @"<fetch version=""1.0"" output-format=""xml-                
    platform"" mapping=""logical"" distinct=""false"">
      <entity name=""new_thing"">
        <attribute name=""new_thingid"" />
        <attribute name=""new_name"" />
        <attribute name=""createdon"" />
        <order attribute=""new_name"" descending=""false"" />
        <filter type=""and"">
          <condition attribute=""statecode"" operator=""eq"" value=""0"" />
        </filter>
      </entity>
    </fetch>";

    try
    {


        var ds = new CRM.CRMService().CreateService() as OrganizationServiceProxy;

        using (var service = new CrmServiceClient(ds))
        {
            if (service.IsReady)
            {
                Console.WriteLine($"Connected to Dynamics 365: {ConfigurationManager.AppSettings["CRM.ServiceUrl"]}");


                // Retrieve the workflow by name
                var query = new QueryExpression("workflow");
                query.ColumnSet.AddColumns("workflowid");
                query.Criteria.AddCondition("name", ConditionOperator.Equal, WORKFLOW_NAME);

                Entity workflowEntity = service.RetrieveMultiple(query).Entities.FirstOrDefault();
                if (workflowEntity != null)
                {


                    // Retrieve entities using FetchXML query
                    EntityCollection entityCollection = service.RetrieveMultiple(new FetchExpression(FETCH_XML_QUERY));


                    Console.WriteLine($"Retrieved {entityCollection.Entities.Count} entities.");
                    Console.WriteLine($"Run workflow: \"{WORKFLOW_NAME}\" ? Y or N");


                    var key = Console.ReadLine();
                    if (key.ToLower() == "y")
                    {
                        if (entityCollection.Entities.Count > 0)
                        {
                            int i = 1;
                            // Trigger the workflow for each entity
                            foreach (var entity in entityCollection.Entities)
                            {
                                service.Execute(new ExecuteWorkflowRequest
                                {
                                    WorkflowId = workflowEntity.Id,
                                    EntityId = entity.Id
                                });

                                Console.WriteLine($"{i++} of {entityCollection.Entities.Count}: Workflow {WORKFLOW_NAME} triggered for entity with ID: {entity.Id}");
                            }
                        }
                        else
                        {
                            Console.WriteLine("No entities found based on the query.");
                        }

                    }
                }
                else
                {
                    Console.WriteLine($"No workflow found by name:\"{WORKFLOW_NAME}\"");
                }
            }
            else
            {
                Console.WriteLine("Failed to connect to Dynamics 365.");
            }
        }
    }
    catch (Exception ex)
    {

        Console.WriteLine($"Error: {ex.Message}");
    }

    Console.WriteLine("Press any key to close.");
    Console.ReadLine();
}

}

c# dynamics-crm workflow
2个回答
0
投票

FetchExpression 和 EntityCollection 原生支持分页。
像这样的东西应该对你有用:

EntityCollection entityCollection = null;
string pagingCookie = null;
int pageNumber = 0;

do
{
    pageNumber++;
    
    // Set Paging Cookie
    string fetchQuery = SetPagingInformation(FETCH_XML_QUERY, 1000, pageNumber, entityCollection?.PagingCookie ?? String.Empty);
    
    // Execute Fetch
    entityCollection = service.RetrieveMultiple(new FetchExpression(fetchQuery));
    
    // Your existing code goes here - just gets repeated for each page
}
while (entityCollection.MoreRecords);


// Helper Method that sets paging info on fetchxml
private string SetPagingInformation(string fetchQuery, int batchSize, int page, string pagingCookie) 
{
    fetchXml = new XmlDocument();
    fetchXml.LoadXml(fetchXml);
            
    fetchXml.DocumentElement.SetAttribute("count", batchSize.ToString());
    fetchXml.DocumentElement.SetAttribute("page", page.ToString());
    fetchXml.DocumentElement.SetAttribute("paging-cookie", pagingCookie);
    
    return fetchXml.OuterXml;
}

关键点是实体集合中的分页cookie可以嵌入到获取查询中以支持分页。我相信 SDK 中有具体的例子

这是一个微软页面,其中包含更多详细信息: https://learn.microsoft.com/en-us/power-apps/developer/data-platform/org-service/page-large-result-sets-with-fetchxml


-1
投票

您可以手动进行寻呼。您正在获取排序的项目列表,因此记录您获得的姓氏并从那里开始新的获取(名称>=last_name_value)。只需记录您已经处理过的姓氏记录的 ID,这样您就不会对其进行两次处理。

© www.soinside.com 2019 - 2024. All rights reserved.