CRM 2013 – Bulk Update/Create – ExecuteMultipleRequest

Hallo Leute,

willkommen im neuen Jahr ­čśë Hat ein wenig gedauert bis zu meinem ersten Blog-Eintrag im neuen Jahr.

Heute m├Âchte ich euch zeigen, wie man schnell und einfach mehrere Entit├Ąten updated, ohne mehrere Webservice-Calls ausl├Âsen zu m├╝ssen. Mit CRM 2013 (auch CRM 2011 mit einem der letzten Update Rollups) besteht nun die M├Âglichkeit einen sog. „ExecuteMultipleRequest“ durchzuf├╝hren. Diesem Objekt f├╝gt man einfach mehrere Requests hinzu (UpdateRequest, CreateRequest) und f├╝hrt ihn aus. Seht selbst:

/// <summary>
        /// Setzt alle ├╝bergebenen XyzCode zu IsDefault = false
        /// </summary>
        /// <param name="serviceContext">The service context.</param>
        /// <param name="XyzCode">The sap codes.</param>
        /// <exception cref="Microsoft.Xrm.Sdk.InvalidPluginExecutionException">
        /// </exception>
        private void SetXyzCodeToDefaultFalse(XrmServiceContext serviceContext, List<xxx_SapCode> XyzCode)
        {

            if (XyzCode.Any())
            {
                var bulkRequest = new ExecuteMultipleRequest()
                {
                    // Assign settings that define execution behavior: continue on error, return responses. 
                    Settings = new ExecuteMultipleSettings()
                    {
                        ContinueOnError = false,
                        ReturnResponses = true
                    },

                    // Create an empty organization request collection.
                    Requests = new OrganizationRequestCollection()
                };

                foreach (var sapCode in XyzCode)
                {
                    var sapCodeToUpdate = new xxx_SapCode
                    {
                        Id = sapCode.Id,
                        xxx_IsDefault = false,
                        EntityState =  EntityState.Changed
                    };

                    // updated entity must be added to a updateMultipleRequest
                    var updateRequest = new UpdateRequest() {Target = sapCodeToUpdate};
                    bulkRequest.Requests.Add(updateRequest);
                }
                
                // Execute all the requests in the request collection using a single web method call.
                var bulkResponse = (ExecuteMultipleResponse) serviceContext.Execute(bulkRequest);

                var sbErrorMessage = new StringBuilder();

                // There should be no responses unless there was an error. Only the first error 
                // should be returned. That is the behavior defined in the settings.
                if (bulkResponse.Responses.Count > 0)
                {
                    foreach (var responseItem in bulkResponse.Responses)
                    {
                        if (responseItem.Fault != null)
                        {
                            var requestItem = bulkRequest.Requests[responseItem.RequestIndex] as UpdateRequest;
                            if (requestItem == null)
                                throw new InvalidPluginExecutionException(
                                    string.Format("RequestItem for ResponseIndex {0} was not found.",
                                        responseItem.RequestIndex));

                            var updateItem = requestItem.Target as xxx_SapCode;
                        }
                    }
                }

                if (sbErrorMessage.ToString().Length > 0)
                {
                    sbErrorMessage.Insert(0,
                        "There occured an error while updating following items: " + Environment.NewLine);

                    throw new InvalidPluginExecutionException(sbErrorMessage.ToString());
                }
            }
        }

Wichtig ist noch, dass man den Response analysiert und ggf. aufgetretene Fehler abf├Ąngt. Daf├╝r sieht man sich responseItem.Fault an (Fault = true = Fehler) Ich erledige das am einfachsten mit einem StringBuilder-Objekt, dem ich nach und nach die Fehlermeldungen hinzuf├╝ge (responseItem.Fault.Message).

Gutes Gelingen!

Cheers,
Chris

Leave a reply