You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dynamics CRM批量更新事务批量大小问题及关联联系人创建保障问询

问题描述

需求

  • 从API读取数据,更新Account(账户)的部分字段,并为其创建对应的Contact(联系人)记录。
  • 需处理约10万条记录,计划使用ExecuteTransactionRequest或ExecuteMultipleRequest批量执行;因需确保账户更新后同步创建联系人,故选用ExecuteTransactionRequest。

当前问题

当前设置当请求批次数量达到500时执行事务,但批次中同时包含Account更新请求和Contact创建请求,可能出现批次凑不满500条而未执行的情况,如何确保每个更新后的Account都能正确创建对应的Contact?

现有代码

var requests = new ExecuteTransactionRequest
{
    Requests = new OrganizationRequestCollection(),
    ReturnResponses = returnResponses
};

foreach (var customer in customerList)
{
    string custNo = customer.GetAttributeValue<string>("customernumber");

    // 从其他API获取客户详情
    var custInfo = await CustomerService.Get(custNo);

    // 更新客户表字段
    Entity cust = new Entity("account");
    cust.Id = customer.Id;
    cust["companytypecode"] = custInfo.EntityTypeCode;
    cust["companytypedescription"] = custInfo.EntityTypeDescription;
    

    var roles = custInfo.Roles.Where(c => c.RoleStatus == "ACTIVE").ToArray();
    // 为每个账户创建联系人
    foreach(var role in roles)
    {
        Entity contact = new Entity("contact");
        contact["FirstName"] = role.RolePerson?.FirstName;
        contact["MiddleName"] = role.RolePerson?.MiddleNames;
        contact["LastName"] = role.RolePerson?.LastName;
        contact["AccountId"] = new EntityReference("account", customer.Id);

        CreateRequest createRequest = new CreateRequest { Target = contact };
        requests.Requests.Add(createRequest);
    }
    
    UpdateRequest updateRequest = new UpdateRequest { Target = cust };
    requests.Requests.Add(updateRequest);

    if (requests.Requests.Count == 500) // 问题:因为包含联系人创建请求,批次不会按单个账户执行,如何确保每个请求都正确执行?
    {
        service.Execute(requests);
        requests.Requests.Clear();
    }
}
// 处理剩余的账户请求
if (requests.Requests.Count > 0)
{
    service.Execute(requests);
}

解决方案

核心思路是把单个Account的更新和其对应的所有Contact创建请求作为一组原子操作,同时控制每个ExecuteTransactionRequest的总请求数不超过Dynamics 365默认的500上限,既保证每个Account操作的完整性,又兼顾批量执行的性能。

具体实现步骤

  1. 按Account分组处理请求:每个Account对应的更新请求+所有关联联系人的创建请求为一组,确保这组操作要么全部成功,要么全部回滚。
  2. 动态管控批次容量:每次添加一组请求前,检查当前批次总请求数是否会超过上限,若超过则先执行现有批次再添加新组。
  3. 收尾剩余请求:循环结束后执行所有未提交的剩余请求。

修改后的代码

// 单批次最大请求数(遵循Dynamics 365限制)
const int maxBatchRequestCount = 500;
var currentTransactionBatch = new ExecuteTransactionRequest
{
    Requests = new OrganizationRequestCollection(),
    ReturnResponses = returnResponses
};

foreach (var customer in customerList)
{
    string custNo = customer.GetAttributeValue<string>("customernumber");
    var custInfo = await CustomerService.Get(custNo);

    // 构建Account更新请求
    var accountUpdateReq = new UpdateRequest
    {
        Target = new Entity("account")
        {
            Id = customer.Id,
            ["companytypecode"] = custInfo.EntityTypeCode,
            ["companytypedescription"] = custInfo.EntityTypeDescription
        }
    };

    // 构建该Account对应的所有Contact创建请求
    var contactCreateReqs = custInfo.Roles
        .Where(r => r.RoleStatus == "ACTIVE")
        .Select(role => new CreateRequest
        {
            Target = new Entity("contact")
            {
                ["FirstName"] = role.RolePerson?.FirstName,
                ["MiddleName"] = role.RolePerson?.MiddleNames,
                ["LastName"] = role.RolePerson?.LastName,
                ["AccountId"] = new EntityReference("account", customer.Id)
            }
        })
        .ToList();

    // 计算当前Account组的总请求数
    int currentGroupCount = 1 + contactCreateReqs.Count;

    // 如果当前批次加新组会超限,先执行现有批次
    if (currentTransactionBatch.Requests.Count + currentGroupCount > maxBatchRequestCount)
    {
        service.Execute(currentTransactionBatch);
        currentTransactionBatch.Requests.Clear();
    }

    // 将当前Account的所有请求加入批次
    currentTransactionBatch.Requests.Add(accountUpdateReq);
    currentTransactionBatch.Requests.AddRange(contactCreateReqs);
}

// 执行最后剩余的请求批次
if (currentTransactionBatch.Requests.Count > 0)
{
    service.Execute(currentTransactionBatch);
}

关键说明

  • 原子性保障:单个Account的更新和联系人创建请求连续加入批次,ExecuteTransactionRequest会按顺序执行所有请求,一旦某一步失败,整个批次会回滚。如果需要更严格的单Account独立事务,可以为每个Account单独创建ExecuteTransactionRequest,但会增加API调用次数,需在性能与原子性间权衡。
  • 容量管控:提前计算每组请求数量,避免批次超限导致执行失败,同时尽可能让批次接近500请求上限,减少API调用次数,提升10万条记录的处理效率。
  • 兼容性:完全贴合Dynamics 365的批量请求限制,不会出现因请求数超限导致的异常。

内容的提问来源于stack exchange,提问作者MVC_Nhibernate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:25:50