Dynamics CRM SDK: выполнение нескольких запросов для массового обновления около 5000 записей

Я написал функцию для обновления прайс-листа по умолчанию для всех активных продуктов в CRM 2013 Online.

//The method takes IOrganization service and total number of records to be created as input
private void UpdateMultipleProducts(IOrganizationService service, int batchSize, EntityCollection UpdateProductsCollection, Guid PriceListGuid)
{
    //To execute the request we have to add the Microsoft.Xrm.Sdk of the latest SDK as reference
    ExecuteMultipleRequest req = new ExecuteMultipleRequest();
    req.Requests = new OrganizationRequestCollection();
    req.Settings = new ExecuteMultipleSettings();
    req.Settings.ContinueOnError = true;
    req.Settings.ReturnResponses = true;
    try
    {

        foreach (var entity in UpdateProductsCollection.Entities)
        {
            UpdateRequest updateRequest = new UpdateRequest { Target = entity };
            entity.Attributes["pricelevelid"] = new EntityReference("pricelevel", PriceListGuid);
            req.Requests.Add(updateRequest);
        }
        var res = service.Execute(req) as ExecuteMultipleResponse;  //Execute the collection of requests
    }

        //If the BatchSize exceeds 1000 fault will be thrown.In the catch block divide the records into batchable records and create
    catch (FaultException<OrganizationServiceFault> fault)
    {
        if (fault.Detail.ErrorDetails.Contains("MaxBatchSize"))
        {
            var allowedBatchSize = Convert.ToInt32(fault.Detail.ErrorDetails["MaxBatchSize"]);
            int remainingCreates = batchSize;

            while (remainingCreates > 0)
            {
                var recordsToCreate = Math.Min(remainingCreates, allowedBatchSize);
                UpdateMultipleProducts(service, recordsToCreate, UpdateProductsCollection, PriceListGuid);
                remainingCreates -= recordsToCreate;
            }
        }
    }
}

Код Описание: В системе имеется около 5000 активных записей продуктов. Поэтому я обновляю прайс-лист по умолчанию для всех из них, используя приведенный выше код.

Но мне здесь чего-то не хватает, поэтому он обновил только 438 записей. Он правильно перебирает оператор While, но здесь он не обновляет их все.

Каким должен быть размер пакета, когда мы запускаем эту функцию в первый раз?

Кто-нибудь может помочь мне здесь?

Спасибо,

Миттал.


person Mittal Patel    schedule 24.03.2014    source источник


Ответы (2)


Вы передаете remainingCreates в качестве параметра batchSize, но ваш код никогда не ссылается на batchSize, поэтому вы просто будете каждый раз повторно вводить этот цикл while.

Кроме того, я не уверен, как вы выполняете всю свою обработку ошибок, но вам нужно обновить свой блок catch, чтобы он не просто пропускал FaultExceptions, если они не содержат значение MaxBatchSize. Прямо сейчас, если вы возьмете FaultException в отношении чего-то другого, кроме размера партии, это будет проигнорировано.

{
    if (fault.Detail.ErrorDetails.Contains("MaxBatchSize"))
    {
        var allowedBatchSize = Convert.ToInt32(fault.Detail.ErrorDetails["MaxBatchSize"]);
        int remainingCreates = batchSize;

        while (remainingCreates > 0)
        {
            var recordsToCreate = Math.Min(remainingCreates, allowedBatchSize);
            UpdateMultipleProducts(service, recordsToCreate, UpdateProductsCollection, PriceListGuid);
            remainingCreates -= recordsToCreate;
        }
    }
    else throw;
}
person Nicknow    schedule 24.03.2014

Вместо реактивной обработки я предпочитаю упреждающую обработку MaxBatchSize, это верно, когда вы уже знаете, что такое MaxMatchSize.

Ниже приведен пример кода, здесь при добавлении OrgRequest в коллекцию я веду подсчет пакетов, и когда он превышается, я вызываю Execute и сбрасываю коллекцию, чтобы получить новую партию.

foreach (DataRow dr in statusTable.Rows)
{
    Entity updEntity = new Entity("ABZ_NBA");
    updEntity["ABZ_NBAid"] = query.ToList().Where(a => a.NotificationNumber == dr["QNMUM"].ToString()).FirstOrDefault().TroubleTicketId;
    //updEntity["ABZ_makerfccall"] = false;
    updEntity["ABZ_rfccall"] = null;

    updEntity[cNBAttribute.Key] = dr["test"];
    req.Requests.Add(new UpdateRequest() { Target = updEntity });

    if (req.Requests.Count == 1000)
    {
        responseWithResults = (ExecuteMultipleResponse)_orgSvc.Execute(req);
        req.Requests = new OrganizationRequestCollection();
    }
}

if (req.Requests.Count > 0)
{
    responseWithResults = (ExecuteMultipleResponse)_orgSvc.Execute(req);
}
person MaKeer    schedule 01.04.2014