private void execWFs(object sender) { if (ExecutionRecordSet.Entities.Count <= 0) { MessageBox.Show("Please click 'Count Records' before Executing Workflows"); return; } #region Bulk Data API Stuff // Create an ExecuteMultipleRequest object. requestWithResults = new ExecuteMultipleRequest() { // Assign settings that define execution behavior: continue on error, return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = false }, // Create an empty organization request collection. Requests = new OrganizationRequestCollection() }; #endregion if (txtBatch.Text != "") { emrBatchSize = Convert.ToInt32(txtBatch.Text); } else { emrBatchSize = 200; } /* this.Invoke((MethodInvoker)delegate() { toolStripProgressBar1.Style = ProgressBarStyle.Marquee; toolStripStatusLabel1.Text = "Executing Workflows"; emrBatchSize = Convert.ToInt32(txtBatchSize.Text); }); */ foreach (var item in ExecutionRecordSet.Entities) { ExecuteWorkflowRequest _execWF = new ExecuteWorkflowRequest { WorkflowId = _selectedWorkflow.Id, EntityId = item.Id }; RunEMR(_execWF, ((BackgroundWorker)sender)); } FlushEMR((BackgroundWorker)sender); /* this.Invoke((MethodInvoker)delegate() { toolStripProgressBar1.Style = ProgressBarStyle.Continuous; toolStripStatusLabel1.Text = "Execution of Workflows Completed"; }); */ }
public BatchOperation() { var executeMultipleRequest = new ExecuteMultipleRequest(); executeMultipleRequest.Settings = new ExecuteMultipleSettings() { ContinueOnError = false, ReturnResponses = true }; executeMultipleRequest.Requests = new OrganizationRequestCollection(); Request = executeMultipleRequest; Operations = new List<ICrmOperation>(); }
public static void Should_Execute_Subsequent_Requests() { var context = new XrmFakedContext(); var service = context.GetFakedOrganizationService(); var account1 = new Account { Id = Guid.NewGuid(), Name = "Acc1" }; var account2 = new Account { Id = Guid.NewGuid(), Name = "Acc2" }; var executeMultipleRequest = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ReturnResponses = true }, Requests = new OrganizationRequestCollection { new CreateRequest { Target = account1 }, new CreateRequest { Target = account2 } } }; var response = service.Execute(executeMultipleRequest) as ExecuteMultipleResponse; Assert.False(response.IsFaulted); Assert.NotEmpty(response.Responses); Assert.NotNull(service.Retrieve(Account.EntityLogicalName, account1.Id, new ColumnSet(true))); Assert.NotNull(service.Retrieve(Account.EntityLogicalName, account2.Id, new ColumnSet(true))); }
public void Execute(IServiceProvider serviceProvider) { //Extract the tracing service for use in debugging sandboxed plug-ins. ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); // Obtain the execution context from the service provider. IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); // The InputParameters collection contains all the data passed in the message request. if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) { // Obtain the target entity from the input parameters. Entity account = (Entity)context.InputParameters["Target"]; string desc = account.Attributes["description"].ToString(); decimal annualRevenue = 0; // If user updates revenue attribute if (account.Attributes.Contains("revenue")) { annualRevenue = ((Money)account.Attributes["revenue"]).Value; } else { // Handling when user does not update revenue attribute Entity preAccount = (Entity)context.PreEntityImages["PreImage"]; if (preAccount.Attributes.Contains("revenue")) { annualRevenue = ((Money)preAccount.Attributes["revenue"]).Value; } } if (context.Depth > 1) { return; } account.Attributes["description"] = annualRevenue.ToString() + desc; service.Update(account); // Retrieve related benefits // Different ways of querying data from CRM // 1. Query Expression // 2. Query By Attribute // 3. Fetchxml // 4. LINQ // Trying 1st method: Query Expression QueryExpression query = new QueryExpression("lexmark_benefit"); query.ColumnSet.AddColumn("lexmark_benefitid"); ConditionExpression cond1 = new ConditionExpression("attrbute1", ConditionOperator.Equal, "value"); ConditionExpression cond2 = new ConditionExpression("attribute2", ConditionOperator.Equal, ""); FilterExpression filter = new FilterExpression(); filter.FilterOperator = LogicalOperator.Or; filter.Conditions.Add(cond1); filter.Conditions.Add(cond2); query.Criteria.AddFilter(filter); EntityCollection collection = service.RetrieveMultiple(query); ExecuteMultipleRequest mutipleReq = new ExecuteMultipleRequest(); //req.Requests = //service.RetrieveMultiple() // ExecuteWorkflowRequest workflowRequest = new ExecuteWorkflowRequest(); // workflowRequest.EntityId = ""; // workflowRequest.WorkflowId = // workflowRequest. CreateEntityRequest req = new CreateEntityRequest() { Entity = new Microsoft.Xrm.Sdk.Metadata.EntityMetadata() { LogicalName = "lexmark_benefit", IsActivity = false, IsAuditEnabled = new BooleanManagedProperty(true), EntityColor = "x100000", DisplayName = new Label("Benefit", 1033), DisplayCollectionName = new Label("Benefits", 1033), IsBPFEntity = true, IsDuplicateDetectionEnabled = new BooleanManagedProperty(true), OwnershipType = Microsoft.Xrm.Sdk.Metadata.OwnershipTypes.UserOwned } }; // ExportSolutionRequest // UpdateRequest updateReq; foreach (Entity benefit in collection.Entities) { updateReq = new UpdateRequest(); benefit.Attributes.Add("lexmark_description", annualRevenue.ToString() + "\n" + desc); updateReq.Target = benefit; mutipleReq.Requests.Add(updateReq); // service.Update(benefit); } ExecuteMultipleResponse res = (ExecuteMultipleResponse) service.Execute(mutipleReq); } }
private void UploadReports() { if (Service == null) { MessageBox.Show("Please connect first", "no connection"); return; } EnableControls(false); WorkAsync(new WorkAsyncInfo { Message = "upload reports...", Work = (w, e) => { var req = new ExecuteMultipleRequest() { Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = true }, Requests = new OrganizationRequestCollection() }; var entUpdateList = new List <Entity>(); foreach (DataGridViewRow row in gridReports.Rows) { if (row.Cells["Aktualisieren"].Value != null && (bool)row.Cells["Aktualisieren"].Value == true && row.Cells["Pfad"].Value != null) { var reportUpdate = new Entity("report"); reportUpdate["bodytext"] = File.ReadAllText((string)row.Cells["Pfad"].Value); if (row.Cells["Id"] != null && row.Cells["Id"].Value != null) { reportUpdate.Id = (Guid)row.Cells["Id"].Value; } else { // to do: set parameters for create // this active version supports only updating existing reports -> have to find out which parameter must be set for create } entUpdateList.Add(reportUpdate); } } if (entUpdateList.Count > 0) { e.Result = UpdateOrCreateEntities(Service, entUpdateList); } }, ProgressChanged = e => { SetWorkingMessage("Upload Reports..."); }, PostWorkCallBack = e => { CheckReports(); if (e.Result != null) { var res = (List <UpdateOrCreateEntitiesResult>)e.Result; foreach (var resItem in res) { var id = Guid.Empty; if (resItem.Request.GetType() == typeof(CreateRequest)) { id = ((CreateRequest)resItem.Request).Target.Id; } else if (resItem.Request.GetType() == typeof(UpdateRequest)) { id = ((UpdateRequest)resItem.Request).Target.Id; } foreach (DataGridViewRow row in gridReports.Rows) { if (row.Cells["Id"] != null && row.Cells["Id"].Value != null && (Guid)row.Cells["Id"].Value == id) { row.Cells["Status"].Value = resItem.Fault.Message; row.Cells["Status"].Style.ForeColor = Color.Red; } } } } EnableControls(true); }, AsyncArgument = null, IsCancelable = true, MessageWidth = 340, MessageHeight = 150 }); }
private void UpdateWebResources(List <WebResourceItem> items) { //TODO: Handle CRM 2011 w/o execute multiple ExecuteMultipleRequest emRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings { ContinueOnError = false, ReturnResponses = true } }; OrganizationRequestCollection requests = new OrganizationRequestCollection(); string projectName = ((ComboBoxItem)Projects.SelectedItem).Content.ToString(); Project project = GetProjectByName(projectName); if (project == null) { return; } string publishXml = "<importexportxml><webresources>"; foreach (var webResourceItem in items) { Entity webResource = new Entity("webresource") { Id = webResourceItem.WebResourceId }; string filePath = Path.GetDirectoryName(project.FullName) + webResourceItem.BoundFile.Replace("/", "\\"); if (!File.Exists(filePath)) { continue; } string content = File.ReadAllText(filePath); webResource["content"] = EncodeString(content); UpdateRequest request = new UpdateRequest { Target = webResource }; requests.Add(request); publishXml += "<webresource>{" + webResource.Id + "}</webresource>"; } publishXml += "</webresources></importexportxml>"; PublishXmlRequest pubRequest = new PublishXmlRequest { ParameterXml = publishXml }; requests.Add(pubRequest); emRequest.Requests = requests; string connString = ((CrmConn)Connections.SelectedItem).ConnectionString; CrmConnection connection = CrmConnection.Parse(connString); using (OrganizationService orgService = new OrganizationService(connection)) { DisplayStatusMessage("Updating & publishing web resources"); ExecuteMultipleResponse emResponse = (ExecuteMultipleResponse)orgService.Execute(emRequest); foreach (var responseItem in emResponse.Responses) { if (responseItem.Fault == null) { continue; } //Some error - do something //TODO: handle error DisplayStatusMessage(String.Empty); return; } MessageBox.Show("Published");//change to status message that goes away itself DisplayStatusMessage(String.Empty); } }
private void UpdateAndPublishMultiple(CrmConnection connection, ProjectItem projectItem, Guid webResourceId) { try { ExecuteMultipleRequest emRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings { ContinueOnError = false, ReturnResponses = true } }; OrganizationRequestCollection requests = new OrganizationRequestCollection(); string publishXml = "<importexportxml><webresources>"; Entity webResource = new Entity("webresource") { Id = webResourceId }; string extension = Path.GetExtension(projectItem.FileNames[1]); string content = extension != null && (extension.ToUpper() != ".TS") ? File.ReadAllText(projectItem.FileNames[1]) : File.ReadAllText(Path.ChangeExtension(projectItem.FileNames[1], ".js")); webResource["content"] = EncodeString(content); UpdateRequest request = new UpdateRequest { Target = webResource }; requests.Add(request); publishXml += "<webresource>{" + webResource.Id + "}</webresource>"; publishXml += "</webresources></importexportxml>"; PublishXmlRequest pubRequest = new PublishXmlRequest { ParameterXml = publishXml }; requests.Add(pubRequest); emRequest.Requests = requests; using (OrganizationService orgService = new OrganizationService(connection)) { _dte.StatusBar.Text = "Updating & publishing web resource..."; _dte.StatusBar.Animate(true, vsStatusAnimation.vsStatusAnimationDeploy); ExecuteMultipleResponse emResponse = (ExecuteMultipleResponse)orgService.Execute(emRequest); bool wasError = false; foreach (var responseItem in emResponse.Responses) { if (responseItem.Fault == null) continue; _logger.WriteToOutputWindow( "Error Updating And Publishing Web Resources To CRM: " + responseItem.Fault.Message + Environment.NewLine + responseItem.Fault.TraceText, Logger.MessageType.Error); wasError = true; } if (wasError) MessageBox.Show("Error Updating And Publishing Web Resources To CRM. See the Output Window for additional details."); else _logger.WriteToOutputWindow("Updated And Published Web Resource", Logger.MessageType.Info); } } catch (FaultException<OrganizationServiceFault> crmEx) { _logger.WriteToOutputWindow("Error Updating And Publishing Web Resource To CRM: " + crmEx.Message + Environment.NewLine + crmEx.StackTrace, Logger.MessageType.Error); } catch (Exception ex) { _logger.WriteToOutputWindow("Error Updating And Publishing Web Resource To CRM: " + ex.Message + Environment.NewLine + ex.StackTrace, Logger.MessageType.Error); } _dte.StatusBar.Clear(); _dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); }
public void CreateEntity(string excelFile, EntityTemplate entityTemplate, Action<string> setMessageOfTheDayLabel) { errorList = new List<Exception>(); warningList = new List<Exception>(); createAttributeRequestList = new List<CreateAttributeRequest>(); createdGlobalOptionSetList = new List<string>(); createWebResourcesRequestList = new List<CreateRequest>(); if (entityTemplate == null) { errorList.Add( new Exception(string.Format("CreateEntity method EntityTemplate reference is null. File: {0}", excelFile))); entityTemplate=new EntityTemplate(){Errors = new List<Exception>()}; entityTemplate.Errors.AddRange(errorList); return; } if (entityTemplate.WillCreateEntity) { var createrequest = new CreateEntityRequest(); var entityMetadata = new EntityMetadata { SchemaName = entityTemplate.LogicalName, DisplayName = GetLabelWithLocalized(entityTemplate.DisplayName), DisplayCollectionName = GetLabelWithLocalized(entityTemplate.DisplayNamePlural), Description = GetLabelWithLocalized(entityTemplate.Description), OwnershipType = DefaultConfiguration.DefaultOwnershipType, IsActivity = false }; createrequest.PrimaryAttribute = GetPrimaryAttribute(entityTemplate); createrequest.Entity = entityMetadata; ExecuteOperation(GetSharedOrganizationService(), createrequest, string.Format("An error occured while creating the entity: {0}", entityTemplate.LogicalName)); //setMessageOfTheDayLabel("1"); if (entityTemplate.AttributeList == null) { entityTemplate.Warnings.AddRange(warningList); entityTemplate.Errors.AddRange(errorList); } foreach (var attributeTemplate in entityTemplate.AttributeList) { CreateAttribute(entityTemplate.LogicalName, attributeTemplate); } } var requests = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection() }; if (entityTemplate.WebResource != null) { for (var i = 0; i < entityTemplate.WebResource.Count; i++) { var webresourceRequest = GetCreateWebResourceRequest(entityTemplate.WebResource[i]); requests.Requests.Add(webresourceRequest); if (i % DefaultConfiguration.ExecuteMultipleSize == 0 || createAttributeRequestList.Count - i < 10) { ExecuteMultipleWebresourceRequests(requests); //setMessageOfTheDayLabel(requests.Requests.Count); requests = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection() }; } } } ExecuteMultipleOperation("Execute multiple error occured.", setMessageOfTheDayLabel); entityTemplate.Warnings.AddRange(warningList); entityTemplate.Errors.AddRange(errorList); }
private void UpdateAndPublishMultiple(CrmServiceClient client, ProjectItem projectItem, Guid webResourceId) { try { ExecuteMultipleRequest emRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings { ContinueOnError = false, ReturnResponses = true } }; OrganizationRequestCollection requests = new OrganizationRequestCollection(); string publishXml = "<importexportxml><webresources>"; Entity webResource = new Entity("webresource") { Id = webResourceId }; string extension = Path.GetExtension(projectItem.FileNames[1]); string content = extension != null && (extension.ToUpper() != ".TS") ? File.ReadAllText(projectItem.FileNames[1]) : File.ReadAllText(Path.ChangeExtension(projectItem.FileNames[1], ".js")); webResource["content"] = EncodeString(content); UpdateRequest request = new UpdateRequest { Target = webResource }; requests.Add(request); publishXml += "<webresource>{" + webResource.Id + "}</webresource>"; publishXml += "</webresources></importexportxml>"; PublishXmlRequest pubRequest = new PublishXmlRequest { ParameterXml = publishXml }; requests.Add(pubRequest); emRequest.Requests = requests; _dte.StatusBar.Text = "Updating & publishing web resource..."; _dte.StatusBar.Animate(true, vsStatusAnimation.vsStatusAnimationDeploy); ExecuteMultipleResponse emResponse = (ExecuteMultipleResponse)client.OrganizationServiceProxy.Execute(emRequest); bool wasError = false; foreach (var responseItem in emResponse.Responses) { if (responseItem.Fault == null) { continue; } _logger.WriteToOutputWindow( "Error Updating And Publishing Web Resources To CRM: " + responseItem.Fault.Message + Environment.NewLine + responseItem.Fault.TraceText, Logger.MessageType.Error); wasError = true; } if (wasError) { MessageBox.Show("Error Updating And Publishing Web Resources To CRM. See the Output Window for additional details."); } else { _logger.WriteToOutputWindow("Updated And Published Web Resource", Logger.MessageType.Info); } } catch (FaultException <OrganizationServiceFault> crmEx) { _logger.WriteToOutputWindow("Error Updating And Publishing Web Resource To CRM: " + crmEx.Message + Environment.NewLine + crmEx.StackTrace, Logger.MessageType.Error); } catch (Exception ex) { _logger.WriteToOutputWindow("Error Updating And Publishing Web Resource To CRM: " + ex.Message + Environment.NewLine + ex.StackTrace, Logger.MessageType.Error); } _dte.StatusBar.Clear(); _dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); }
private static ExecuteMultipleRequest CreateExecuteMultipleRequest() { var request = new ExecuteMultipleRequest() { // Assign settings that define execution behavior: continue on error, return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = true }, // Create an empty organization request collection. Requests = new OrganizationRequestCollection() }; return request; }
public void LoadComponentLayer(RunWorkerCompletedEventArgs args) { WorkAsync(new WorkAsyncInfo() { Message = "Loading Layers", IsCancelable = true, Work = (bgworker, workargs) => { if (CancelOperation) { OperationRunning = false; return; } var sw = Stopwatch.StartNew(); var total = AllSolutionComponent.Count; var current = 0; var loaded = 0; var results = new List <RetrieveMultipleResponse>(); var batch = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ContinueOnError = true, ReturnResponses = true }, Requests = new OrganizationRequestCollection() }; foreach (var component in AllSolutionComponent) { current++; var pct = 100 * current / total; if (component.GetAttributeValue <OptionSetValue>("componenttype") != null) { QueryExpression queryExpression = new QueryExpression("msdyn_componentlayer"); queryExpression.Criteria.AddCondition("msdyn_solutionname", ConditionOperator.Equal, "Active"); queryExpression.Criteria.AddCondition("msdyn_solutioncomponentname", ConditionOperator.Equal, ((ComponentType)component.GetAttributeValue <OptionSetValue>("componenttype").Value).ToString()); queryExpression.Criteria.AddCondition("msdyn_componentid", ConditionOperator.Equal, component.GetAttributeValue <Guid>("objectid").ToString()); queryExpression.ColumnSet = new ColumnSet(true); RetrieveMultipleRequest retrieveMultipleRequest = new RetrieveMultipleRequest { Query = queryExpression, }; batch.Requests.Add(retrieveMultipleRequest); if (batch.Requests.Count == 1000 || current == total) { bgworker.ReportProgress(pct, $"Retrieving Components Active Layers {current} of {total}"); var result = Service.Execute(batch) as ExecuteMultipleResponse; loaded += batch.Requests.Count; results.AddRange(result.Responses.Select(x => x.Response as RetrieveMultipleResponse)); batch.Requests.Clear(); batch = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ContinueOnError = true, ReturnResponses = true }, Requests = new OrganizationRequestCollection() }; } if (CancelOperation) { break; } } } sw.Stop(); workargs.Result = results; }, PostWorkCallBack = LoadComponentsDefinitions, ProgressChanged = (changeargs) => { SetWorkingMessage(changeargs.UserState.ToString()); } }); }
public static void WriteRecordsToCrm(List <AdhocImportRecord> newRecords) { List <AdhocImportRecord> redoRecords = new List <AdhocImportRecord>(); ExecuteMultipleRequest executeMultipeRequest = new ExecuteMultipleRequest() { Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = true }, Requests = new OrganizationRequestCollection() }; SkuEntityItem skuItem = null; BusinessUnitEntityItem businessUnitItem = null; foreach (AdhocImportRecord itemRecord in newRecords) { skuItem = tempSkus.Where(x => x.SkuValue == itemRecord.ProductSku).FirstOrDefault(); businessUnitItem = tempBusinessUnits.Where(x => x.CountryCode == itemRecord.CountryCode).FirstOrDefault(); if (skuItem != null && businessUnitItem != null) { itemRecord.ProcessType += "New create;"; redoRecords.Add(itemRecord); ExecuteTransactionRequest newRequest = ProcessRecord(itemRecord, skuItem.SkuEntity, businessUnitItem.BusinessUnitEntity); executeMultipeRequest.Requests.Add(newRequest); } else { itemRecord.ProcessType += "Can't create due to empty SKU or BusinessUnit;"; redoRecords.Add(itemRecord); } } string redoRecordsFile = csvOutputFile + "_redoRecords.txt"; WriteListFile(redoRecords, redoRecordsFile); string executeMultipeRequestFile = csvOutputFile + "_executeMultipeResult.txt"; StreamWriter redoRecordsResultfile = new StreamWriter(executeMultipeRequestFile, true); #region Execute Multiple Request within Transation if (executeMultipeRequest.Requests.Count() > 0) { try { // Execute Multiple Request ExecuteMultipleResponse response = (ExecuteMultipleResponse)_serviceProxy.Execute(executeMultipeRequest); String faultMesg = String.Empty; foreach (ExecuteMultipleResponseItem responseItem in response.Responses) { if (responseItem.Fault != null) { faultMesg += GetFaultInfo(executeMultipeRequest.Requests[responseItem.RequestIndex], responseItem.RequestIndex, responseItem.Fault); } } if (faultMesg != String.Empty) { redoRecordsResultfile.Write(faultMesg); } } catch (FaultException <OrganizationServiceFault> mex) { redoRecordsResultfile.Write($"Fail to fix import data due to {mex.Message}."); } } redoRecordsResultfile.Close(); #endregion Execute Multiple Request within Transation }
private ExecuteResponse ExecuteWorkflow(QueryExpression query, Guid workflowId, int page) { var response = new ExecuteResponse(); try { query.PageInfo.Count = 100; query.PageInfo.PageNumber = page; var result = OrganizationService.RetrieveMultiple(query); response.HasMoreResults = result.MoreRecords; response.ProcessedCount = result.Entities.Count; var em = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ContinueOnError = false, ReturnResponses = true } }; em.Requests = new OrganizationRequestCollection(); em.Requests.AddRange(result.Entities.Select(e => new ExecuteWorkflowRequest { EntityId = e.Id, WorkflowId = workflowId })); var emResponse = (ExecuteMultipleResponse)OrganizationService.Execute(em); if (emResponse.IsFaulted) { var firstFault = emResponse.Responses.Where(r => r.Fault != null) .FirstOrDefault(); response.HasError = true; response.ErrorMessage = firstFault != null ? firstFault.Fault.Message : "Unknown execute workflow error"; return response; } } catch (Exception ex) { response.HasError = true; response.ErrorMessage = ex.Message; } return response; }
public static bool UpdateBatch(this IOrganizationService organizationService, List<Entity> batchEntities, int countEntitiesPerBatch = 100) { if (batchEntities == null) { throw new ArgumentNullException(); } var pages = batchEntities.ToPages(countEntitiesPerBatch); foreach (var page in pages) { // Create an ExecuteMultipleRequest object. var multipleRequest = 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() }; // Add a UpdateRequest for each entity to the request collection. foreach (var entity in page.Value) { var updateRequest = new UpdateRequest { Target = entity }; multipleRequest.Requests.Add(updateRequest); } // Execute all the requests in the request collection using a single web method call. var multipleResponse = (ExecuteMultipleResponse)organizationService.Execute(multipleRequest); } return true; }
/// <summary> /// Call this method for bulk delete /// </summary> /// <param name="service">Org Service</param> /// <param name="entityReferences">Collection of EntityReferences to Delete</param> public static void DeleteBatch(this IOrganizationService service, IEnumerable<EntityReference> entityReferences) { var pages = entityReferences.ToList() .ToPages(500); foreach (var page in pages) { // Create an ExecuteMultipleRequest object. var multipleRequest = 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() }; // Add a DeleteRequest for each entity to the request collection. foreach (var entityRef in page.Value) { var deleteRequest = new DeleteRequest { Target = entityRef }; multipleRequest.Requests.Add(deleteRequest); } // Execute all the requests in the request collection using a single web method call. var multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest); } }
private List<Tuple<Guid, string, byte[]>> UpdateImages(BackgroundWorker bw, List<Entity> entityRecords, string attribute, string entityName) { var timer = Stopwatch.StartNew(); imageCache.Clear(); int rowNumber = 1, totalRecords = entityRecords.Count; var imageList = new ImageList(); imageList.ColorDepth = ColorDepth.Depth32Bit; imageList.ImageSize = new Size(40, 40); lvResults.SmallImageList = imageList; var imageIndex = 0; var requests = 0; ExecuteMultipleRequest executeMultipleRequests = new ExecuteMultipleRequest(); executeMultipleRequests.Settings = new ExecuteMultipleSettings { ContinueOnError = true, ReturnResponses = true }; executeMultipleRequests.Requests = new OrganizationRequestCollection(); //https://msdn.microsoft.com/en-us/library/hh195051%28v=vs.110%29.aspx var imageTaskList = new List<KeyValuePair<Tuple<Entity, string>, Task<byte[]>>>(); foreach (var entity in entityRecords) { var attributeValue = entity.GetAttributeValue<string>(attribute); if (string.IsNullOrEmpty(attributeValue) || imageTaskList.Any(x => x.Key.Item2 == attributeValue)) continue; var logoTask = Task.Run(() => { bw.ReportProgress(0, $"Record {rowNumber++} of {totalRecords} : Retrieving image for {attributeValue}"); return GetLogo(entity, attributeValue); }); imageTaskList.Add(new KeyValuePair<Tuple<Entity, string>, Task<byte[]>>( new Tuple<Entity, string>(entity, attributeValue), logoTask)); } var imageTasks = imageTaskList.Select(x => x.Value).ToList(); Task.WaitAll(imageTasks.ToArray()); var updatedImages = imageCache.ToList(); foreach (var entity in entityRecords) { var updateEntity = new Entity { Id = entity.Id, LogicalName = entity.LogicalName }; var attributeValue = entity.GetAttributeValue<string>(attribute); var entityImage = updatedImages.SingleOrDefault(x=>x.Item2 == attributeValue)?.Item3; if (entityImage == null) continue; updateEntity["entityimage"] = entityImage; executeMultipleRequests.Requests.Add(new UpdateRequest { Target = updateEntity }); bw.ReportProgress(0, $"Preparing update request for {attribute}"); requests++; if (requests == 100 || entityRecords.Count == requests) { bw.ReportProgress(0, $"Executing update requests for {attribute}"); ExecuteMultipleUpdates(updatedImages, executeMultipleRequests); executeMultipleRequests.Requests.Clear(); requests = 0; } } //Process any leftover requests if (executeMultipleRequests.Requests.Any()) { bw.ReportProgress(0, "Pushing through final set of update requests"); ExecuteMultipleUpdates(updatedImages, executeMultipleRequests); } var imageConverter = new ImageConverter(); var displayColumn = ListViewDelegates.GetSelectedItems(lvEntities)[0].SubItems[2].Text; foreach (var entity in entityRecords) { var attributeValue = entity.GetAttributeValue<string>(attribute); var primaryDisplayName = entity.GetAttributeValue<string>(displayColumn); var entityImage = updatedImages.SingleOrDefault(x => x.Item2 == attributeValue)?.Item3; if (entityImage == null) continue; var imageListImage = imageConverter.ConvertFrom(entityImage) as Bitmap; imageList.Images.Add(imageListImage); var listViewItem = new ListViewItem($"{primaryDisplayName} ({attributeValue})"); listViewItem.Tag = $"{ConnectionDetail.WebApplicationUrl}main.aspx?etn={entityName}&pagetype=entityrecord&id={entity.Id}"; listViewItem.ImageIndex = imageIndex++; lvResults.Items.Add(listViewItem); } timer.Stop(); MessageBox.Show($"{lvResults.Items.Count} images updated in {timer.ElapsedMilliseconds / 1000} second(s)", "Success", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); return updatedImages; }
private ExecuteMultipleResponse ExecuteInternal(ExecuteMultipleRequest request) { var settings = request.Settings; var response = new ExecuteMultipleResponse(); response.Results["Responses"] = new ExecuteMultipleResponseItemCollection(); for(int i=0; i<request.Requests.Count; i++) { var childRequest = request.Requests[i]; OrganizationServiceFault fault = null; OrganizationResponse childResponse = null; try { if (childRequest.RequestName == "ExecuteMultiple") { throw new Exception("ExecuteMultipleRequest cannot contain an ExecuteMultipleRequest"); } childResponse = ExecuteInternal((dynamic) childRequest); if (!settings.ReturnResponses) { childResponse = null; } } catch (NotImplementedException) { throw; } catch (FaultException<OrganizationServiceFault> ex) { response["IsFaulted"] = true; fault = ex.Detail; fault.ErrorDetails["CallStack"] = ex.StackTrace; if (!settings.ContinueOnError) { break; } } catch (Exception ex) { response["IsFaulted"] = true; fault = new OrganizationServiceFault {Message = ex.Message, Timestamp = DateTime.UtcNow}; fault.ErrorDetails["CallStack"] = ex.StackTrace; if (!settings.ContinueOnError) { break; } } finally { if (childResponse != null || fault != null) { response.Responses.Add(new ExecuteMultipleResponseItem { Fault = fault, RequestIndex = i, Response = childResponse }); } } } return response; }
public void ExecuteBulkAssignRequests(ExecuteMultipleRequest request) { throw new NotImplementedException(); }
private void MenuItemCallback(object sender, EventArgs e) { var dte = (EnvDTE.DTE) this.ServiceProvider.GetService(typeof(EnvDTE.DTE)); dte.StatusBar.Animate(true, vsStatusAnimation.vsStatusAnimationDeploy); var activeDocument = dte.ActiveDocument; var solutionFullName = dte.Solution.FullName; var fInfo = new FileInfo(solutionFullName); var devKitCrmConfigFile = $"{fInfo.DirectoryName}\\PL.DynamicsCrm.DevKit.json"; dte.StatusBar.Text = "Read PL.DynamicsCrm.DevKit.json config"; var config = DevKitCrmConfigHelper.GetDevKitCrmConfig(dte); var defaultConnection = config.CrmConnections.Where(conn => conn.Name == config.DefaultCrmConnection).FirstOrDefault(); if (defaultConnection == null) { ShowError("Default Crm connection not found!"); goto CLEAR_STATUS; } if (string.IsNullOrEmpty(config.SolutionPrefix)) { ShowError("PL.DynamicsCrm.DevKit.json config not found SolutionPrefix data"); goto CLEAR_STATUS; } dte.StatusBar.Text = "Connecting ..."; var check = SharedGlobals.GetGlobal("CrmService", dte); if (check == null) { try { var uri = new Uri(defaultConnection.Url); var clientCredentials = new ClientCredentials(); clientCredentials.UserName.UserName = defaultConnection.UserName; clientCredentials.UserName.Password = defaultConnection.Password; check = new OrganizationServiceProxy(uri, null, clientCredentials, null); SharedGlobals.SetGlobal("CrmService", check, dte); } catch { ShowError("Connecting Fail!"); goto CLEAR_STATUS; } } var crmService = (OrganizationServiceProxy)SharedGlobals.GetGlobal("CrmService", dte); dte.StatusBar.Text = "Connected ..."; var fileName = activeDocument.FullName; var parts = fileName.Split("\\".ToCharArray()); var condition = string.Empty; for (var i = 1; i < parts.Length; i++) { var value = $"{config.SolutionPrefix}/{parts[i]}/"; for (var j = i + 1; j < parts.Length; j++) { value += $"{parts[j]}/"; } if (value.EndsWith("/")) { value = value.TrimEnd("/".ToCharArray()); } condition += $"<condition attribute='name' operator='ends-with' value='{value}'/>"; } var fetchXml = $@" <fetch> <entity name='webresource'> <attribute name='name' /> <filter type='or'> {condition} </filter> </entity> </fetch>"; var rows = crmService.RetrieveMultiple(new FetchExpression(fetchXml)); if (rows.Entities.Count == 0) { ShowError("Web resource not found!"); goto CLEAR_STATUS; } var webResourceId = rows.Entities[0].Id; try { ExecuteMultipleRequest emRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings { ContinueOnError = false, ReturnResponses = true } }; OrganizationRequestCollection requests = new OrganizationRequestCollection(); string publishXml = "<importexportxml><webresources>"; Entity webResource = new Entity("webresource") { Id = webResourceId }; string content = File.ReadAllText(fileName); webResource["content"] = EncodeString(content); UpdateRequest request = new UpdateRequest { Target = webResource }; requests.Add(request); publishXml += "<webresource>{" + webResource.Id + "}</webresource>"; publishXml += "</webresources></importexportxml>"; PublishXmlRequest pubRequest = new PublishXmlRequest { ParameterXml = publishXml }; requests.Add(pubRequest); emRequest.Requests = requests; dte.StatusBar.Text = "Updating & publishing web resource..."; ExecuteMultipleResponse emResponse = (ExecuteMultipleResponse)crmService.Execute(emRequest); bool wasError = false; foreach (var responseItem in emResponse.Responses) { if (responseItem.Fault == null) { continue; } wasError = true; } if (wasError) { ShowError("Error Updating And Publishing Web Resources To CRM. See the Output Window for additional details."); goto CLEAR_STATUS; } else { dte.StatusBar.Text = "Updated And Published Web Resource"; goto CLEAR_STATUS; } } catch (FaultException <OrganizationServiceFault> crmEx) { ShowError("Error Updating And Publishing Web Resource To CRM: " + crmEx.Message + Environment.NewLine + crmEx.StackTrace); goto CLEAR_STATUS; } catch (Exception ex) { ShowError("Error Updating And Publishing Web Resource To CRM: " + ex.Message + Environment.NewLine + ex.StackTrace); } CLEAR_STATUS: dte.StatusBar.Clear(); dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); }
public ActionResult RetrieveOrcidProfile() { // if the user is anonymus or null, redirect them to the signin page if (!InitializeOrcidController()) { // TODO give a better error around not already being signed in. return(Redirect("/SignIn/")); } if (string.IsNullOrEmpty(UserAuthorizationToken)) { // user authorization token is not defined } record userRecord = OrcidClient.GetUserRecord(); // Create the entity contact to update. Contact contact = new Contact(); contact.Id = xrmUser.ContactId.Id; contact.rp2_OricdBiography = userRecord?.person?.biography?.content; service = HttpContext.GetOrganizationService(); service.Update(contact); if (userRecord.activitiessummary == null) { return(Redirect("/profile/orcid/")); } ExecuteMultipleRequest mRequest = new ExecuteMultipleRequest(); mRequest.Settings = new ExecuteMultipleSettings(); mRequest.Settings.ContinueOnError = true; mRequest.Settings.ReturnResponses = false; mRequest.Requests = new OrganizationRequestCollection(); employments userEmployments = OrcidClient.GetUserOrcidData <employments>(userRecord.activitiessummary.employments.path); if (userEmployments?.employmentsummary != null) { foreach (employmentsummary es in userEmployments.employmentsummary) { rp2_employment employment = new rp2_employment("rp2_sourceidentifier", es.path); employment.rp2_Person = xrmUser.ContactId; employment.rp2_Department = es?.departmentname; employment.rp2_OrganizationNameText = es?.organization?.name; employment.rp2_RoleTitle = es.roletitle; employment.rp2_City = es.organization?.address?.city; employment.rp2_Country = es.organization?.address?.country.ToString(); employment.rp2_StateProvince = es.organization?.address?.region; employment.rp2_EndDate = es.enddate?.ToDateTime(); employment.rp2_StartDate = es.startdate?.ToDateTime(); //service.Create(employment); UpsertRequest cRq = new UpsertRequest(); cRq.Target = employment; mRequest.Requests.Add(cRq); } } if (mRequest.Requests.Count > 0) { ExecuteMultipleResponse response = service.Execute(mRequest) as ExecuteMultipleResponse; // TODO validate resonse var errorFaults = response.Responses.Where(r => r.Fault != null); if (errorFaults.Any()) { string errorMessages = "{" + string.Join("}, {", errorFaults.Select(f => f.Fault.Message)) + "}"; throw new Exception(errorMessages); } } return(Redirect("/profile/orcid/")); }
public void Should_Be_Able_To_Insert_And_Retrieve_Inserted_Account_In_Single_Bulk_Request() { var connectionString = ConfigurationManager.ConnectionStrings["CrmOrganisation"]; using (var conn = new CrmDbConnection(connectionString.ConnectionString)) { conn.Open(); var orgService = conn.OrganizationService; // Create an ExecuteMultipleRequest object. var multipleRequests = 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() }; var entity = new Entity("account"); entity.Id = Guid.NewGuid(); entity["name"] = "experimental test"; CreateRequest createRequest = new CreateRequest { Target = entity }; RetrieveRequest retrieveRequest = new RetrieveRequest { Target = new EntityReference(entity.LogicalName, entity.Id), ColumnSet = new ColumnSet("createdon") }; multipleRequests.Requests.Add(createRequest); multipleRequests.Requests.Add(retrieveRequest); // Execute all the requests in the request collection using a single web method call. ExecuteMultipleResponse responseWithResults = (ExecuteMultipleResponse)orgService.Execute(multipleRequests); var createResponseItem = responseWithResults.Responses[0]; CreateResponse createResponse = null; if (createResponseItem.Response != null) { createResponse = (CreateResponse)createResponseItem.Response; } var retrieveResponseItem = responseWithResults.Responses[1]; RetrieveResponse retrieveResponse = null; if (retrieveResponseItem.Response != null) { retrieveResponse = (RetrieveResponse)retrieveResponseItem.Response; } Console.Write(retrieveResponse.Entity["createdon"]); } }
public void AddRolesToPrincipals(List <Entity> roles, List <Entity> principals, List <Entity> allRoles, BackgroundWorker worker = null) { int total = principals.Count * roles.Count; int current = 0; var execMulti = new ExecuteMultipleRequest() { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = true } }; foreach (var principal in principals) { foreach (var role in roles) { // allow the user to cancel if (worker.CancellationPending && worker.WorkerSupportsCancellation) { return; } if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(current * 100 / total, "Adding roles to principals ({0} %)..."); } var roleToUse = role; if (allRoles != null) { var currentPrincipalBuId = principal.GetAttributeValue <EntityReference>("businessunitid").Id; if (role.GetAttributeValue <EntityReference>("businessunitid").Id != currentPrincipalBuId) { roleToUse = GetRoleRecursive(currentPrincipalBuId, new List <Entity> { role }, allRoles); } } try { // batch the requests across users and roles execMulti.Requests.Add(new AssociateRequest() { Target = principal.ToEntityReference(), Relationship = new Relationship(principal.LogicalName + "roles_association"), RelatedEntities = new EntityReferenceCollection { roleToUse.ToEntityReference() } }); } catch { // ignored } current++; // execute the batch once we either meet the batch size or we hit the total if ((current % BatchSize == 0) || (current == total)) { var resp = service.Execute(execMulti); execMulti.Requests.Clear(); } } } }
private List<Tuple<Guid, string, byte[]>> UpdateImages(List<Entity> entityRecords, string attribute) { imageCache.Clear(); byte[] image = null; var imageList = new ImageList(); imageList.ImageSize = new Size(40, 40); lvResults.SmallImageList = imageList; var imageIndex = 0; var requests = 0; ExecuteMultipleRequest executeMultipleRequests = new ExecuteMultipleRequest(); executeMultipleRequests.Settings = new ExecuteMultipleSettings { ContinueOnError = true, ReturnResponses = true }; executeMultipleRequests.Requests = new OrganizationRequestCollection(); foreach (var entity in entityRecords) { var attributeValue = entity.GetAttributeValue<string>(attribute); if (string.IsNullOrEmpty(attributeValue)) continue; //Check if we already have retrived the logo for this value if (!imageCache.Any(x => x.Item2 == attributeValue)) { var imageTask = GetLogo(attributeValue); imageTask.Wait(); image = imageTask.Result; if (image != null) imageCache.Add(new Tuple<Guid, string, byte[]>(entity.Id, attributeValue, image)); } image = imageCache.FirstOrDefault(x => x.Item2 == attributeValue)?.Item3; if (image != null) { entity["entityimage"] = image; executeMultipleRequests.Requests.Add(new UpdateRequest { Target = entity }); requests++; if (requests == 100 || entityRecords.Count == requests) { ExecuteMultipleUpdates(imageCache, executeMultipleRequests); executeMultipleRequests.Requests.Clear(); requests = 0; } } } //Processs any leftover requests if (executeMultipleRequests.Requests.Any()) ExecuteMultipleUpdates(imageCache, executeMultipleRequests); foreach (var updatedImage in imageCache) { var imageListImage = (Bitmap)((new ImageConverter()).ConvertFrom(updatedImage.Item3)); imageList.Images.Add(imageListImage); var listViewItem = new ListViewItem(updatedImage.Item2); listViewItem.ImageIndex = imageIndex++; lvResults.Items.Add(listViewItem); } return imageCache; }
private void AssignRecords() { if (working) { return; } var owner = cbAssignUser.SelectedEntity != null ? cbAssignUser.SelectedEntity : cbAssignTeam.SelectedEntity; var ownername = cbAssignUser.SelectedEntity != null ? "User " + cbAssignUser.Text : "Team " + cbAssignTeam.Text; if (owner == null) { return; } if (MessageBox.Show($"All selected records will unconditionally be reassigned to {ownername}.\n" + "UI defined rules will NOT be enforced.\n" + "Plugins and workflows WILL trigger.\n" + "User privileges WILL be respected.\n\n" + "Please confirm assignment.", "Confirm", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk) != DialogResult.OK) { return; } tsbCancel.Enabled = true; splitContainer1.Enabled = false; working = true; var includedrecords = GetIncludedRecords(); var ignoreerrors = chkIgnoreErrors.Checked; if (!int.TryParse(cmbBatchSize.Text, out int batchsize)) { batchsize = 1; } WorkAsync(new WorkAsyncInfo() { Message = "Assigning records", IsCancelable = true, Work = (bgworker, workargs) => { var sw = Stopwatch.StartNew(); var total = includedrecords.Count(); var current = 0; var assigned = 0; var failed = 0; var batch = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ContinueOnError = ignoreerrors }, Requests = new OrganizationRequestCollection() }; foreach (var record in includedrecords) { if (bgworker.CancellationPending) { workargs.Cancel = true; break; } current++; var pct = 100 * current / total; try { var clone = new Entity(record.LogicalName, record.Id); clone.Attributes.Add("ownerid", owner.ToEntityReference()); if (batchsize == 1) { bgworker.ReportProgress(pct, $"Assigning record {current} of {total}"); Service.Update(clone); assigned++; } else { batch.Requests.Add(new UpdateRequest { Target = clone }); if (batch.Requests.Count == batchsize || current == total) { bgworker.ReportProgress(pct, $"Assigning records {current - batch.Requests.Count + 1}-{current} of {total}"); var response = (ExecuteMultipleResponse)Service.Execute(batch); if (response.IsFaulted && !ignoreerrors) { var firsterror = response.Responses.First(r => r.Fault != null); if (firsterror != null) { throw new Exception(firsterror.Fault.Message); } throw new Exception("Unknown exception during assignment"); } assigned += response.Responses.Count; batch.Requests.Clear(); } } } catch (Exception ex) { failed++; if (!ignoreerrors) { throw ex; } } } sw.Stop(); workargs.Result = new Tuple <int, int, long>(assigned, failed, sw.ElapsedMilliseconds); }, PostWorkCallBack = (completedargs) => { working = false; tsbCancel.Enabled = false; if (completedargs.Error != null) { MessageBox.Show(completedargs.Error.Message, "Assign", MessageBoxButtons.OK, MessageBoxIcon.Error); } else if (completedargs.Cancelled) { if (MessageBox.Show("Operation cancelled!\nRun query to get records again, to verify record information.", "Cancel", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) { RetrieveRecords(fetchXml, RetrieveRecordsReady); } } else if (completedargs.Result is Tuple <int, int, long> result) { lblUpdateStatus.Text = $"{result.Item1} records reassigned, {result.Item2} records failed."; LogUse("Assigned", result.Item1, result.Item3); if (result.Item2 > 0) { LogUse("Failed", result.Item2); } if (MessageBox.Show("Assign completed!\nRun query to get records again?", "Bulk Data Updater", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { RetrieveRecords(fetchXml, RetrieveRecordsReady); } } splitContainer1.Enabled = true; }, ProgressChanged = (changeargs) => { SetWorkingMessage(changeargs.UserState.ToString()); } });
private void ExecuteMultipleOperation(string exceptionMessage, Action<string> setMessageOfTheDayLabel) { var organizationService = GetSharedOrganizationService(); try { if (createAttributeRequestList.Any()) { var executeMultipleRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection() }; for (var i = 0; i < createAttributeRequestList.Count; i++) { executeMultipleRequest.Requests.Add(createAttributeRequestList[i]); if (i%DefaultConfiguration.ExecuteMultipleSize == 0 || createAttributeRequestList.Count-i<10) { ExecuteExecuteMultipleRequest(organizationService, executeMultipleRequest); //setMessageOfTheDayLabel(executeMultipleRequest.Requests.Count); executeMultipleRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection() }; } } } if (createWebResourcesRequestList.Any()) { var executeMultipleRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection() }; for (var i = 0; i < createWebResourcesRequestList.Count; i++) { executeMultipleRequest.Requests.Add(createWebResourcesRequestList[i]); if (i % DefaultConfiguration.ExecuteMultipleSize == 0 || createAttributeRequestList.Count - i < 10) { ExecuteExecuteMultipleRequest(organizationService, executeMultipleRequest); //setMessageOfTheDayLabel(executeMultipleRequest.Requests.Count); executeMultipleRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection() }; } } } } catch (Exception ex) { var exception = new Exception(exceptionMessage, ex); errorList.Add(exception); } }
/// <summary> /// Executes multiple deletes concurrently within one or more Batches, with each batch limited to 1000 records. /// </summary> /// <param name="serviceManager"></param> /// <param name="recordsToBeDeleted"></param> /// <param name="totalRequestsPerBatch"></param> /// <returns></returns> public static List <Guid> DeleteParallelExecuteMultiple(OrganizationServiceManager serviceManager, EntityCollection recordsToBeDeleted, int totalRequestsPerBatch) { int batchSize = 0; int recordsToBeDeletedCount = recordsToBeDeleted.Entities.Count; int batchNumber = (int)Math.Ceiling((recordsToBeDeleted.Entities.Count * 1.0d) / (totalRequestsPerBatch * 1.0d)); Console.WriteLine(); log.Info("Delete Mode: Parallel Execute Multiple"); List <Guid> ids = new List <Guid>(); IDictionary <string, ExecuteMultipleRequest> requests = new Dictionary <string, ExecuteMultipleRequest>(); for (int i = 0; i < batchNumber; i++) { ExecuteMultipleRequest executeMultipleRequest = new ExecuteMultipleRequest() { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = true }, RequestId = Guid.NewGuid() }; for (int j = recordsToBeDeleted.Entities.Count - 1; j >= 0; j--) { Entity entityToBeDeleted = recordsToBeDeleted.Entities[j]; ids.Add(entityToBeDeleted.Id); DeleteRequest deleteRequest = new DeleteRequest() { Target = new EntityReference(entityToBeDeleted.LogicalName, entityToBeDeleted.Id), RequestId = Guid.NewGuid() }; executeMultipleRequest.Requests.Add(deleteRequest); recordsToBeDeleted.Entities.RemoveAt(j); if (batchSize == totalRequestsPerBatch - 1) // If we reach the batch limit, break from the loop { break; } batchSize++; } batchSize = 0; requests.Add(new KeyValuePair <string, ExecuteMultipleRequest>(i.ToString(), executeMultipleRequest)); log.InfoFormat("Request Id for request batch number {0}: {1}", i, executeMultipleRequest.RequestId); } log.InfoFormat("Deleting {0} record(s)...", recordsToBeDeletedCount); Stopwatch sw = new Stopwatch(); sw.Start(); // Parallel execution of all ExecuteMultipleRequest in the requests Dictionary IDictionary <string, ExecuteMultipleResponse> responseForDeleteRecords = serviceManager.ParallelProxy.Execute <ExecuteMultipleRequest, ExecuteMultipleResponse>(requests); int threadsCount = Process.GetCurrentProcess().Threads.Count; sw.Stop(); log.InfoFormat("Number of threads used: {0}", threadsCount); log.InfoFormat("Seconds to delete {0} record(s): {1}s", recordsToBeDeletedCount, sw.Elapsed.TotalSeconds); return(ids); }
/// <summary> /// This sample demonstrates how to execute a collection of message requests using a single web service /// call and optionally return the results. /// </summary> /// <seealso cref="http://msdn.microsoft.com/en-us/library/gg328075.aspx"/> /// <param name="serverConfig">Contains server connection information.</param> /// <param name="promptforDelete">When True, the user will be prompted to delete all /// created entities.</param> public void Run(ServerConnection.Configuration serverConfig, bool promptforDelete) { try { //<snippetExecuteMultiple1> // Get a reference to the organization service. using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri,serverConfig.Credentials, serverConfig.DeviceCredentials)) { // Enable early-bound type support to add/update entity records required for this sample. _serviceProxy.EnableProxyTypes(); #region Execute Multiple with Results // Create an ExecuteMultipleRequest object. requestWithResults = 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() }; // Create several (local, in memory) entities in a collection. EntityCollection input = GetCollectionOfEntitiesToCreate(); // Add a CreateRequest for each entity to the request collection. foreach (var entity in input.Entities) { CreateRequest createRequest = new CreateRequest { Target = entity }; requestWithResults.Requests.Add(createRequest); } // Execute all the requests in the request collection using a single web method call. ExecuteMultipleResponse responseWithResults = (ExecuteMultipleResponse)_serviceProxy.Execute(requestWithResults); // Display the results returned in the responses. foreach (var responseItem in responseWithResults.Responses) { // A valid response. if (responseItem.Response != null) DisplayResponse(requestWithResults.Requests[responseItem.RequestIndex], responseItem.Response); // An error has occurred. else if (responseItem.Fault != null) DisplayFault(requestWithResults.Requests[responseItem.RequestIndex], responseItem.RequestIndex, responseItem.Fault); } //</snippetExecuteMultiple1> #endregion Execute Multiple with Results #region Execute Multiple with No Results ExecuteMultipleRequest requestWithNoResults = new ExecuteMultipleRequest() { // Set the execution behavior to not continue after the first error is received // and to not return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = false, ReturnResponses = false }, Requests = new OrganizationRequestCollection() }; // Update the entities that were previously created. EntityCollection update = GetCollectionOfEntitiesToUpdate(); foreach (var entity in update.Entities) { UpdateRequest updateRequest = new UpdateRequest { Target = entity }; requestWithNoResults.Requests.Add(updateRequest); } ExecuteMultipleResponse responseWithNoResults = (ExecuteMultipleResponse)_serviceProxy.Execute(requestWithNoResults); // 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 (responseWithNoResults.Responses.Count > 0) { foreach (var responseItem in responseWithNoResults.Responses) { if (responseItem.Fault != null) DisplayFault(requestWithNoResults.Requests[responseItem.RequestIndex], responseItem.RequestIndex, responseItem.Fault); } } else { Console.WriteLine("All account records have been updated successfully."); } #endregion Execute Multiple with No Results #region Execute Multiple with Continue On Error ExecuteMultipleRequest requestWithContinueOnError = new ExecuteMultipleRequest() { // Set the execution behavior to continue on an error and not return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = false }, Requests = new OrganizationRequestCollection() }; // Update the entities but introduce some bad attribute values so we get errors. EntityCollection updateWithErrors = GetCollectionOfEntitiesToUpdateWithErrors(); foreach (var entity in updateWithErrors.Entities) { UpdateRequest updateRequest = new UpdateRequest { Target = entity }; requestWithContinueOnError.Requests.Add(updateRequest); } ExecuteMultipleResponse responseWithContinueOnError = (ExecuteMultipleResponse)_serviceProxy.Execute(requestWithContinueOnError); // There should be no responses except for those that contain an error. if (responseWithContinueOnError.Responses.Count > 0) { if (responseWithContinueOnError.Responses.Count < requestWithContinueOnError.Requests.Count) { Console.WriteLine("Response collection contain a mix of successful response objects and errors."); } foreach (var responseItem in responseWithContinueOnError.Responses) { if (responseItem.Fault != null) DisplayFault(requestWithContinueOnError.Requests[responseItem.RequestIndex], responseItem.RequestIndex, responseItem.Fault); } } else { // No errors means all transactions are successful. Console.WriteLine("All account records have been updated successfully."); } #endregion Execute Multiple with Continue On Error DeleteRequiredRecords(promptforDelete); } } // <snippetExecuteMultiple2> catch (FaultException<OrganizationServiceFault> fault) { // Check if the maximum batch size has been exceeded. The maximum batch size is only included in the fault if it // the input request collection count exceeds the maximum batch size. if (fault.Detail.ErrorDetails.Contains("MaxBatchSize")) { int maxBatchSize = Convert.ToInt32(fault.Detail.ErrorDetails["MaxBatchSize"]); if (maxBatchSize < requestWithResults.Requests.Count) { // Here you could reduce the size of your request collection and re-submit the ExecuteMultiple request. // For this sample, that only issues a few requests per batch, we will just print out some info. However, // this code will never be executed because the default max batch size is 1000. Console.WriteLine("The input request collection contains %0 requests, which exceeds the maximum allowed (%1)", requestWithResults.Requests.Count, maxBatchSize); } } // Re-throw so Main() can process the fault. throw; } // </snippetExecuteMultiple2> }
public void ProcessDeletes() { DateTime startTime = DateTime.Now; if (ExecutionRecordSet.Entities.Count == 0) { MessageBox.Show("No records found in this view to delete.", "Bulk Delete Tool"); return; } WorkAsync(new WorkAsyncInfo { //Message = $"Deleting {ExecutionRecordSet.Entities.Count.ToString("#,#", CultureInfo.InvariantCulture)} Records{Environment.NewLine}from{Environment.NewLine}{ExecutionRecordSet.Entities[0].LogicalName}", Message = GetDeleteStatusMessage(ExecutionRecordSet.Entities[0].LogicalName, 0, ExecutionRecordSet.Entities.Count, new TimeSpan()), Work = (w, e) => { this.Invoke((MethodInvoker) delegate() { HideNotification(); toolStripDropDownButton1.Enabled = tsbCount.Enabled = tsbExecute.Enabled = tsbtnHelp.Enabled = tsbtnFetchBuilder.Enabled = false; tsbtnStop.Enabled = true; }); #region Bulk Data API Stuff // Create an ExecuteMultipleRequest object. requestWithResults = new ExecuteMultipleRequest() { // Assign settings that define execution behavior: continue on error, return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = false }, // Create an empty organization request collection. Requests = new OrganizationRequestCollection() }; #endregion Bulk Data API Stuff emrBatchSize = txtBatchSize.Text != "" ? Convert.ToInt32(txtBatchSize.Text) : 200; emrCount = 0; foreach (Entity d in ExecutionRecordSet.Entities) { // Stop if should stop if (w.CancellationPending) { return; } DeleteRequest dr = new DeleteRequest { Target = d.ToEntityReference() }; // Add in EMR stuff here RunEMR(dr, w); if (txtInterval.Text != "0" && !string.IsNullOrWhiteSpace(txtInterval.Text)) { System.Threading.Thread.Sleep(Convert.ToInt16(txtInterval.Text) * 1000); // TODO: Implement Timer Later /* * var statusChecker = new StatusChecker(Convert.ToInt32(txtInterval.Text)); * * // Create a timer that invokes CheckStatus after one second, and every 1 second thereafter. * Console.WriteLine("{0:h:mm:ss.fff} Creating timer.\n", * DateTime.Now); * var stateTimer = new System.Threading.Timer(statusChecker.CheckStatus, w, 1000, 1000); * * // When autoEvent signals, change the period to every half second. * //autoEvent.WaitOne(); * //stateTimer.Change(0, 500); * //Console.WriteLine("\nChanging period to .5 seconds.\n"); * * // When autoEvent signals the second time, dispose of the timer. * //autoEvent.WaitOne(); * stateTimer.Dispose(); * //Console.WriteLine("\nDestroying timer."); */ } } FlushEMR(w); e.Result = ""; // response.UserId; }, ProgressChanged = e => { // If progress has to be notified to user, use the following method: SetWorkingMessage(e.UserState.ToString()); }, PostWorkCallBack = e => { //MessageBox.Show(string.Format("You are {0}", (Guid)e.Result)); tsbtnStop.Enabled = false; toolStripDropDownButton1.Enabled = tsbCount.Enabled = tsbExecute.Enabled = tsbtnHelp.Enabled = tsbtnFetchBuilder.Enabled = true; TimeSpan tsRunTime = DateTime.Now - startTime; MessageBox.Show("Started @ " + startTime.ToShortTimeString() + Environment.NewLine + "Finished @ " + DateTime.Now.ToShortTimeString() + Environment.NewLine + "Total Run Time: " + tsRunTime.ToString("hh\\:mm\\:ss") + Environment.NewLine + Environment.NewLine + string.Format("Records Deleted: {0} / {1}", emrCount.ToString("#,#", CultureInfo.InvariantCulture), ExecutionRecordSet.Entities.Count.ToString("#,#", CultureInfo.InvariantCulture)) + Environment.NewLine + "Errors: " + errorCount.ToString("#,#", CultureInfo.InvariantCulture) , "Bulk Delete Tool"); }, AsyncArgument = null, IsCancelable = true, MessageWidth = 340, MessageHeight = 150 }); }
private DetectionResults GetUsageFetchAggregate(EntityMetadata emd, Settings settings, BackgroundWorker worker = null) { var result = new DetectionResults(); List <AttributeMetadata> attributes = new List <AttributeMetadata>(); var emRequest = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ContinueOnError = true, ReturnResponses = true }, Requests = new OrganizationRequestCollection() }; var fetchXmlAttrPart = $"<attribute name=\"{emd.PrimaryIdAttribute}\" aggregate=\"count\" alias=\"count\"/>"; emRequest.Requests.Add(new RetrieveMultipleRequest { Query = new FetchExpression(string.Format(FetchXml, emd.LogicalName, fetchXmlAttrPart, "", settings.RecordsReturnedPerTrip)) }); var allResult = new ExecuteMultipleResponseItemCollection(); foreach (var attribute in MetadataHelper.FilterAttributes(emd.Attributes).OrderBy(a => a.LogicalName)) { if (settings.FilterAttributes && settings.Filters.ContainsKey(emd.LogicalName)) { EntityFilterSetting fs = settings.Filters[emd.LogicalName]; if (fs.Attributes.Count > 0 && !fs.Attributes.Contains(attribute.LogicalName)) { continue; } if (fs.ShowOnlyCustom && !attribute.IsCustomAttribute.Value) { continue; } if (fs.ShowOnlyStandard && attribute.IsCustomAttribute.Value) { continue; } } attributes.Add(attribute); var fetchXmlConditionNotNullPart = $"<condition attribute=\"{attribute.LogicalName}\" operator=\"not-null\"/>"; emRequest.Requests.Add(new RetrieveMultipleRequest { Query = new FetchExpression(string.Format(FetchXml, emd.LogicalName, fetchXmlAttrPart, fetchXmlConditionNotNullPart, settings.RecordsReturnedPerTrip)) }); if (emRequest.Requests.Count == settings.AttributesReturnedPerTrip) { var tempResults = (ExecuteMultipleResponse)service.Execute(emRequest); allResult.AddRange(tempResults.Responses); emRequest = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ContinueOnError = true, ReturnResponses = true }, Requests = new OrganizationRequestCollection() }; } } var results = (ExecuteMultipleResponse)service.Execute(emRequest); allResult.AddRange(results.Responses); var allResponse = (RetrieveMultipleResponse)allResult[0].Response; if (allResult[0].Fault != null) { result.IsAggregateQueryRecordLimitReached = allResult[0].Fault.ErrorCode == -2147164125; result.Fault = allResult[0].Fault; return(result); } var allCount = allResponse != null ? allResponse.EntityCollection.Entities.First().GetAttributeValue <AliasedValue>("count") : null; var allCountValue = allCount != null ? (int)allCount.Value : 0; result.Total = allCountValue; result.Entity = emd.LogicalName; foreach (var attribute in attributes) { var index = attributes.IndexOf(attribute); var resultNotNull = allResult[index + 1]; if (resultNotNull.Fault != null) { result.Fault = resultNotNull.Fault; return(result); } var notNullValueAliased = ((RetrieveMultipleResponse)resultNotNull.Response).EntityCollection.Entities.First() .GetAttributeValue <AliasedValue>("count"); var notNullValue = (int?)notNullValueAliased?.Value ?? 0; result.Results.Add(new DetectionResult { Attribute = attribute, NotNull = notNullValue, Percentage = allCountValue != 0 ? (double)notNullValue * 100 / allCountValue : 0 }); } return(result); }
private void UpdateRecords() { if (working) { return; } if (MessageBox.Show("All selected records will unconditionally be updated.\nUI defined rules will NOT be enforced.\n\nConfirm update!", "Confirm", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk) != DialogResult.OK) { return; } tsbCancel.Enabled = true; splitContainer1.Enabled = false; var selectedattributes = lvAttributes.Items.Cast <ListViewItem>().Select(i => i.Tag as BulkActionItem).ToList(); var entity = records.EntityName; var includedrecords = GetIncludedRecords(); working = true; var ignoreerrors = chkIgnoreErrors.Checked; if (!int.TryParse(cmbUpdBatchSize.Text, out int batchsize)) { batchsize = 1; } if (!int.TryParse(cmbUpdDelayCall.Text, out int delaytime)) { delaytime = 0; } WorkAsync(new WorkAsyncInfo() { Message = "Updating records", IsCancelable = true, AsyncArgument = selectedattributes, Work = (bgworker, workargs) => { var sw = Stopwatch.StartNew(); var total = includedrecords.Entities.Count; var waitnow = false; var waitcur = 0; var current = 0; var updated = 0; var failed = 0; var attributes = workargs.Argument as List <BulkActionItem>; var batch = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ContinueOnError = ignoreerrors }, Requests = new OrganizationRequestCollection() }; foreach (var record in includedrecords.Entities) { if (bgworker.CancellationPending) { workargs.Cancel = true; break; } current++; var pct = 100 * current / total; if (waitnow && delaytime > 0) { waitcur = delaytime; while (waitcur > 0) { bgworker.ReportProgress(pct, $"Waiting between calls - {waitcur} sec{Environment.NewLine}(Next update {current} of {total})"); if (waitcur > 10) { System.Threading.Thread.Sleep(10000); waitcur -= 10; } else { System.Threading.Thread.Sleep(waitcur * 1000); waitcur = 0; } if (bgworker.CancellationPending) { workargs.Cancel = true; break; } } waitnow = false; } if (!CheckAllUpdateAttributesExistOnRecord(record, attributes)) { //if ((bai.DontTouch || bai.Action == BulkActionAction.Touch) && !attributesexists) bgworker.ReportProgress(pct, "Reloading record " + current.ToString()); LoadMissingAttributesForRecord(record, entity, attributes); } try { if (GetUpdateRecord(record, attributes) is Entity updateentity) { if (batchsize == 1) { bgworker.ReportProgress(pct, $"Updating record {current} of {total}"); Service.Update(updateentity); updated++; waitnow = true; } else { batch.Requests.Add(new UpdateRequest { Target = updateentity }); if (batch.Requests.Count == batchsize || current == total) { bgworker.ReportProgress(pct, $"Updating records {current - batch.Requests.Count + 1}-{current} of {total}"); Service.Execute(batch); updated += batch.Requests.Count; batch.Requests.Clear(); waitnow = true; } } } } catch (Exception ex) { failed++; if (!chkIgnoreErrors.Checked) { throw ex; } } } sw.Stop(); workargs.Result = new Tuple <int, int, long>(updated, failed, sw.ElapsedMilliseconds); }, PostWorkCallBack = (completedargs) => { working = false; tsbCancel.Enabled = false; if (completedargs.Error != null) { MessageBox.Show(completedargs.Error.Message, "Update", MessageBoxButtons.OK, MessageBoxIcon.Error); } else if (completedargs.Cancelled) { if (MessageBox.Show("Operation cancelled!\nRun query to get records again, to verify updated values.", "Cancel", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) { RetrieveRecords(fetchXml, RetrieveRecordsReady); } } else if (completedargs.Result is Tuple <int, int, long> result) { lblUpdateStatus.Text = $"{result.Item1} records updated, {result.Item2} records failed."; LogUse("Updated", result.Item1, result.Item3); if (result.Item2 > 0) { LogUse("Failed", result.Item2); } if (MessageBox.Show("Update completed!\nRun query to show updated records?", "Bulk Data Updater", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { RetrieveRecords(fetchXml, RetrieveRecordsReady); } } splitContainer1.Enabled = true; }, ProgressChanged = (changeargs) => { SetWorkingMessage(changeargs.UserState.ToString()); } });
protected override void Execute(CodeActivityContext executionContext) { var tracingService = executionContext.GetExtension <ITracingService>(); var context = executionContext.GetExtension <IWorkflowContext>(); var serviceFactory = executionContext.GetExtension <IOrganizationServiceFactory>(); var service = serviceFactory.CreateOrganizationService(context.UserId); var batch = batchSize.Get(executionContext); if (batch > 4999) { batch = 4999; } isMoreRecords.Set(executionContext, true); try { tracingService.Trace("start of download: " + DateTime.Now); var query = new QueryExpression { EntityName = "eti_accountproduct", ColumnSet = new ColumnSet("eti_promoexpires", "eti_ratetoset", "eti_producttoswap", "eti_keepcontent"), Criteria = { FilterOperator = LogicalOperator.And, Conditions = { new ConditionExpression { AttributeName = "eti_promoexpires", Operator = ConditionOperator.OnOrBefore, Values = { DateTime.Now.AddDays(-1) } } } } }; query.PageInfo = new PagingInfo(); query.PageInfo.Count = batch; // or 50, or whatever query.PageInfo.PageNumber = 1; tracingService.Trace("start of composing: " + DateTime.Now); var result = service.RetrieveMultiple(query).Entities; tracingService.Trace("end of download: " + DateTime.Now); //define if another loop is required if (result.Count < batch) { isMoreRecords.Set(executionContext, false); } var multipleRequest = new ExecuteMultipleRequest() { // Assign settings that define execution behavior: continue on error, return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = true }, // Create an empty organization request collection. Requests = new OrganizationRequestCollection() }; foreach (Entity en in result) { //if promo has product to swap if (en.Attributes.Contains("eti_keepcontent") && en.GetAttributeValue <bool>("eti_keepcontent") == true) { //set to pending change en.Attributes.Add("eti_productstate", new OptionSetValue(964820002)); //swap product var origProduct = en.GetAttributeValue <EntityReference>("eti_producttoswap"); en.Attributes.Add("eti_product", en.GetAttributeValue <EntityReference>("eti_producttoswap")); en.Attributes["eti_producttoswap"] = origProduct; //eti_productsswapped en.Attributes["eti_productsswapped"] = true; //update price en.Attributes.Add("eti_newrate", en.GetAttributeValue <Money>("eti_ratetoset")); } else { //set to pending remove en.Attributes.Add("eti_productstate", new OptionSetValue(964820003)); en.Attributes["eti_producttoswap"] = null; } //nulify fields en.Attributes["eti_promoexpires"] = null; en.Attributes["eti_ratetoset"] = null; en.Attributes["eti_keepcontent"] = true; UpdateRequest updateRequest = new UpdateRequest { Target = en }; multipleRequest.Requests.Add(updateRequest); } tracingService.Trace("end of composing: " + DateTime.Now); //create executemultiplerequest tracingService.Trace("start of upload: " + DateTime.Now); ExecuteMultipleResponse responseWithResults = (ExecuteMultipleResponse)service.Execute(multipleRequest); tracingService.Trace("end of upload: " + DateTime.Now); } catch (Exception ex) { tracingService.Trace("Error in CreateOrUpdateAccountActivity – " + ex.Message); throw; } }
private string CreateData(EntityCollection entityCollection, BackgroundWorker worker, SetItem setItem, string entityName) { var requestWithResults = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ContinueOnError = false, ReturnResponses = true }, Requests = new OrganizationRequestCollection() }; foreach (var entity in entityCollection.Entities) { if (entity.Attributes.Contains("statecode") && ((OptionSetValue)entity["statecode"]).Value >= 1) // inactive { CreateInactiveRequest(entity); } else { requestWithResults.Requests.Add(new CreateRequest { Target = entity }); } } string errors = string.Empty; if (requestWithResults.Requests.Count > 0) { var responseWithResults = (ExecuteMultipleResponse)Service.Execute(requestWithResults); ai.WriteEvent("Data Mocked Count", requestWithResults.Requests.Count); errors = responseWithResults.Responses.Where(responseItem => responseItem.Fault != null) .Aggregate(errors, (accumulator, responseItem) => accumulator += "\r\n" + responseItem.RequestIndex + " | " + responseItem.Fault); if (setItem != null) { setItem.AddedValues .AddRange( from item in responseWithResults.Responses .Where(ri => ri.Fault == null) .Select(cr => ((CreateResponse)cr.Response)) select new Lookup { guid = item.id, Name = item.id.ToString() }); setItem.entityName = entityName; } //setItem.AddedValues.AddRange(responseWithResults.Responses.Select(ri => new Lookup(){guid = ((CreateResponse) ri.Response).) // else collection.Entities[responseItem.RequestIndex].Id = ((CreateResponse) responseItem.Response).id; //DisplayFault(requestWithResults.Requests[responseItem.RequestIndex], // responseItem.RequestIndex, responseItem.Fault); } foreach (var updateEntity in updateEntities) { errors += SendInactiveRequest(updateEntity, worker, setItem, entityName); } return(errors); // e.Result = errors; }
private void PerformSyncActions(Entity targetGeneric) { targetGeneric.Require(nameof(targetGeneric)); var customJob = new CustomJob(); // post if ((Context as IPluginExecutionContext)?.Stage == 40) { Log.Log("Processing post-operation actions ..."); var postImage = Context.PostEntityImages.FirstOrDefault().Value?.ToEntity <CustomJob>(); if (postImage == null && Context.MessageName == "Update") { throw new InvalidPluginExecutionException("A full post image must be registered on this plugin step."); } postImage = postImage ?? targetGeneric.ToEntity <CustomJob>(); foreach (var attribute in postImage.Attributes) { customJob[attribute.Key] = attribute.Value; } ValidateJobParams(customJob); if (string.IsNullOrEmpty(customJob.Name)) { Log.Log("Name is empty, updating ..."); Service.Update( new CustomJob { Id = customJob.Id, Name = BuildJobName(customJob) }); Log.Log("Name was empty, updated."); } return; } if (Context.MessageName == "Update") { Log.Log("Update message, fetching target job from CRM ..."); customJob = Service.Retrieve(targetGeneric.LogicalName, targetGeneric.Id, new ColumnSet(true)) .ToEntity <CustomJob>(); Log.Log("Fetched target job from CRM."); } foreach (var attribute in targetGeneric.Attributes) { customJob[attribute.Key] = attribute.Value; } // fill page if empty if (customJob.RecordsPerPage != null && customJob.PageNumber == null) { Log.Log("Records per page set, but not the page number; setting to '1'."); targetGeneric[CustomJob.Fields.PageNumber] = 1; } // clear failed targets as we are starting over and reset retry runs if (customJob.StatusReason == CustomJob.StatusReasonEnum.Draft) { Log.Log("Draft status."); Log.Log("Clearing retry run, page number, cookie, and last message."); targetGeneric[CustomJob.Fields.CurrentRetryRun] = null; targetGeneric[CustomJob.Fields.PageNumber] = null; targetGeneric[CustomJob.Fields.PagingCookie] = null; targetGeneric[CustomJob.Fields.LatestRunMessage] = null; Log.Log("Loading failed targets for this job ..."); var tempJob = new CustomJob { Id = customJob.Id }; tempJob.LoadRelation(CustomJob.RelationNames.CustomJobFailedTargetsOfCustomJob, Service); Log.Log("Loaded failed targets for this job."); if (tempJob.CustomJobFailedTargetsOfCustomJob != null) { Log.Log($"Failed targets: {tempJob.CustomJobFailedTargetsOfCustomJob.Length}."); var failures = tempJob.CustomJobFailedTargetsOfCustomJob; var request = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings { ContinueOnError = true, ReturnResponses = false } }; Log.Log($"Deleting failed targets ..."); for (var i = 0; i < Math.Ceiling(failures.Length / 1000d); i++) { request.Requests.Clear(); request.Requests.AddRange(failures.Skip(i * 1000).Take(1000) .Select(failure => new DeleteRequest { Target = new EntityReference(CustomJobFailedTarget.EntityLogicalName, failure.Id) })); Service.Execute(request); } Log.Log($"Deleted failed targets."); } } // cancel active sub-jobs if (customJob.StatusReason == CustomJob.StatusReasonEnum.Draft || customJob.StatusReason == CustomJob.StatusReasonEnum.Cancelled) { Log.Log($"{customJob.StatusReason} status."); var tempJob = new CustomJob { Id = customJob.Id }; Log.Log("Loading active children of this job ..."); var filter = new FilterExpression(); filter.AddCondition(CustomJob.Fields.Status, ConditionOperator.Equal, (int)CustomJob.StatusEnum.Active); tempJob.LoadRelation(CustomJob.RelationNames.CustomJobsOfParentJob, Service, false, filter); Log.Log("Loaded active children of this job."); if (tempJob.CustomJobsOfParentJob != null) { Log.Log($"Active children: {tempJob.CustomJobsOfParentJob.Length}."); foreach (var job in tempJob.CustomJobsOfParentJob) { Log.Log($"Setting sub job '{job.Id}' to cancelled ..."); Service.Update( new CustomJob { Id = job.Id, Status = CustomJob.StatusEnum.Inactive, StatusReason = CustomJob.StatusReasonEnum.Cancelled }); Log.Log($"Set sub job '{job.Id}' to cancelled."); } } } var isNamingFieldsUpdated = targetGeneric.Attributes.Keys .Any(key => new[] { CustomJob.Fields.TargetLogicalName, CustomJob.Fields.ActionName, CustomJob.Fields.Workflow, CustomJob.Fields.TargetID, CustomJob.Fields.TargetXML }.Contains(key)); if (string.IsNullOrEmpty(customJob.Name) || isNamingFieldsUpdated) { targetGeneric[CustomJob.Fields.Name] = BuildJobName(customJob); Log.Log($"Set job name to '{targetGeneric[CustomJob.Fields.Name]}'."); } if (customJob.StatusReason == CustomJob.StatusReasonEnum.Draft && customJob.MarkForWaiting == true && customJob.TargetDate != null && Context.MessageName != "Create") { Log.Log("Setting job to waiting because of flag ..."); targetGeneric[CustomJob.Fields.MarkForWaiting] = false; targetGeneric[CustomJob.Fields.StatusReason] = CustomJob.StatusReasonEnum.Waiting.ToOptionSetValue(); Log.Log("Set job to waiting because of flag."); } }
public static void CreateBulk(EntityCollection ec, bool continueOnError = true) { var service = Connection.Service; var loopCount = (ec.Entities.Count / 1000) + (ec.Entities.Count % 1000 != 0 ? 1 : 0); for (var i = 0; i < loopCount; i++) { try { var multipleRequest = new ExecuteMultipleRequest() { Settings = new ExecuteMultipleSettings() { ContinueOnError = continueOnError, ReturnResponses = true, }, Requests = new OrganizationRequestCollection() }; var start = (i * 1000); var end = ec.Entities.Count <= (i + 1) * 1000 ? ec.Entities.Count : (i + 1) * 1000; for (var j = start; j < end; j++) { var createRequest = new CreateRequest { Target = ec.Entities.ElementAt(j) }; multipleRequest.Requests.Add(createRequest); } // Execute all the requests in the request collection using a single web method call. var multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest); if (!multipleResponse.Responses.Any()) { continue; } foreach (var response in multipleResponse.Responses) { if (response.Fault == null) { continue; } if (response.Fault.InnerFault != null) { //error if (!continueOnError) { throw new Exception(JsonConvert.SerializeObject(response.Fault.InnerFault) + Environment.NewLine + JsonConvert.SerializeObject(ec.Entities[(i * 1000) + response.RequestIndex])); } } else { //error if (!continueOnError) { throw new Exception(JsonConvert.SerializeObject(response.Fault) + Environment.NewLine + JsonConvert.SerializeObject(ec.Entities[(i * 1000) + response.RequestIndex])); } } } } catch (Exception) { throw; } } }
private void SaveGlobalOptionSet() { WorkAsync("Saving global optionset...", (w, e) => { var req = new RetrieveOptionSetRequest() { Name = ((Item)cboOptionSets.SelectedItem).Value, }; var resp = (RetrieveOptionSetResponse)Service.Execute(req); OptionSetMetadata md = (OptionSetMetadata)resp.OptionSetMetadata; //foreach (var option in md.Options) //{ // var delReq = new DeleteOptionValueRequest() // { // OptionSetName = md.Name, // Value = option.Value.Value // }; // Service.Execute(delReq); //} var data = (BindingList<Item>)dgvOptions.DataSource; var execMultiReq = new ExecuteMultipleRequest() { Settings = new Microsoft.Xrm.Sdk.ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = false }, Requests = new Microsoft.Xrm.Sdk.OrganizationRequestCollection() }; foreach (var item in data) { var exists = (from o in md.Options where o.Value.Value == int.Parse(item.Value) select true).FirstOrDefault(); if (exists) { var upReq = new UpdateOptionValueRequest() { OptionSetName = md.Name, Label = new Microsoft.Xrm.Sdk.Label(item.Name, 1033), Value = int.Parse(item.Value) }; execMultiReq.Requests.Add(upReq); } else { var addReq = new InsertOptionValueRequest() { OptionSetName = md.Name, Label = new Microsoft.Xrm.Sdk.Label(item.Name, 1033), Value = int.Parse(item.Value) }; execMultiReq.Requests.Add(addReq); } } foreach (var item in md.Options) { var exists = (from d in data where int.Parse(d.Value) == item.Value.Value select true).FirstOrDefault(); if (!exists) { var delReq = new DeleteOptionValueRequest() { OptionSetName = md.Name, Value = item.Value.Value }; execMultiReq.Requests.Add(delReq); } } Service.Execute(execMultiReq); w.ReportProgress(50, "Publishing global optionset..."); PublishXmlRequest pxReq1 = new PublishXmlRequest { ParameterXml = String.Format("<importexportxml><optionsets><optionset>{0}</optionset></optionsets></importexportxml>", md.Name) }; Service.Execute(pxReq1); }, e => { }, e => { SetWorkingMessage(e.UserState.ToString()); } ); }
private ExecuteMultipleResponse ExecuteMultipleRequest(ExecuteMultipleRequest req) { return((ExecuteMultipleResponse)_service.Execute(req)); }
[STAThread] // Added to support UX static void Main(string[] args) { CrmServiceClient service = null; try { service = SampleHelpers.Connect("Connect"); if (service.IsReady) { #region Sample Code ////////////////////////////////////////////// #region Set up SetUpSample(service); #endregion Set up #region Demonstrate // Create an ExecuteMultipleRequest object. var requestWithResults = 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() }; // Create several (local, in memory) entities in a collection. EntityCollection input = GetCollectionOfEntitiesToCreate(); // Add a CreateRequest for each entity to the request collection. foreach (var entity in input.Entities) { var createRequest = new CreateRequest { Target = entity }; requestWithResults.Requests.Add(createRequest); } // Execute all the requests in the request collection using a single web method call. var responseWithResults = (ExecuteMultipleResponse)service.Execute(requestWithResults); // Display the results returned in the responses. foreach (var responseItem in responseWithResults.Responses) { // A valid response. if (responseItem.Response != null) { DisplayResponse(requestWithResults.Requests[responseItem.RequestIndex], responseItem.Response); } // An error has occurred. else if (responseItem.Fault != null) { DisplayFault(requestWithResults.Requests[responseItem.RequestIndex], responseItem.RequestIndex, responseItem.Fault); } } #endregion Execute Multiple with Results #region Execute Multiple with No Results var requestWithNoResults = new ExecuteMultipleRequest() { // Set the execution behavior to not continue after the first error is received // and to not return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = false, ReturnResponses = false }, Requests = new OrganizationRequestCollection() }; // Update the entities that were previously created. EntityCollection update = GetCollectionOfEntitiesToUpdate(); foreach (var entity in update.Entities) { var updateRequest = new UpdateRequest { Target = entity }; requestWithNoResults.Requests.Add(updateRequest); } ExecuteMultipleResponse responseWithNoResults = (ExecuteMultipleResponse)service.Execute(requestWithNoResults); // 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 (responseWithNoResults.Responses.Count > 0) { foreach (var responseItem in responseWithNoResults.Responses) { if (responseItem.Fault != null) { DisplayFault(requestWithNoResults.Requests[responseItem.RequestIndex], responseItem.RequestIndex, responseItem.Fault); } } } else { Console.WriteLine("All account records have been updated successfully."); } #endregion Execute Multiple with No Results #region Execute Multiple with Continue On Error var requestWithContinueOnError = new ExecuteMultipleRequest() { // Set the execution behavior to continue on an error and not return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = false }, Requests = new OrganizationRequestCollection() }; // Update the entities but introduce some bad attribute values so we get errors. EntityCollection updateWithErrors = GetCollectionOfEntitiesToUpdateWithErrors(); foreach (var entity in updateWithErrors.Entities) { UpdateRequest updateRequest = new UpdateRequest { Target = entity }; requestWithContinueOnError.Requests.Add(updateRequest); } var responseWithContinueOnError = (ExecuteMultipleResponse)service.Execute(requestWithContinueOnError); // There should be no responses except for those that contain an error. if (responseWithContinueOnError.Responses.Count > 0) { if (responseWithContinueOnError.Responses.Count < requestWithContinueOnError.Requests.Count) { Console.WriteLine("Response collection contain a mix of successful response objects and errors."); } foreach (var responseItem in responseWithContinueOnError.Responses) { if (responseItem.Fault != null) { DisplayFault(requestWithContinueOnError.Requests[responseItem.RequestIndex], responseItem.RequestIndex, responseItem.Fault); } } } else { // No errors means all transactions are successful. Console.WriteLine("All account records have been updated successfully."); } #endregion Execute Multiple with Continue On Error #region Clean up CleanUpSample(service); #endregion Clean up } #endregion Demonstrate else { const string UNABLE_TO_LOGIN_ERROR = "Unable to Login to Common Data Service"; if (service.LastCrmError.Equals(UNABLE_TO_LOGIN_ERROR)) { Console.WriteLine("Check the connection string values in cds/App.config."); throw new Exception(service.LastCrmError); } else { throw service.LastCrmException; } } } catch (Exception ex) { SampleHelpers.HandleException(ex); } finally { if (service != null) { service.Dispose(); } Console.WriteLine("Press <Enter> to exit."); Console.ReadLine(); } }
public static void RunVatUpdate(IOrganizationService conn) { var vats = VatInfo.GetVatList(); var pagingQuery = new QueryExpression("account"); pagingQuery.ColumnSet = new ColumnSet("accountnumber"); Queue <Entity> allEnts = new Queue <Entity>(); while (true) { var results = conn.RetrieveMultiple(pagingQuery); if (results.Entities != null && results.Entities.Any()) { results.Entities.ToList().ForEach(allEnts.Enqueue); } if (!results.MoreRecords) { break; } pagingQuery.PageInfo.PageNumber++; pagingQuery.PageInfo.PagingCookie = results.PagingCookie; } ExecuteMultipleRequest emr = null; while (allEnts.Any()) { if (emr == null) { emr = new ExecuteMultipleRequest() { Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = true }, Requests = new OrganizationRequestCollection() } } ; var ent = allEnts.Dequeue(); if (vats.ContainsKey(ent.GetAttributeValue <string>("accountnumber"))) { var newEnt = new Entity("account", ent.Id); newEnt.Attributes.Add("new_vatno", vats[ent.GetAttributeValue <string>("accountnumber")].TaxNumber); newEnt.Attributes.Add("new_registrationnumber", vats[ent.GetAttributeValue <string>("accountnumber")].RegistrationNumber); emr.Requests.Add(new UpdateRequest() { Target = newEnt }); } if (emr.Requests.Count >= maxBatchSize) { try { var emResponse = (ExecuteMultipleResponse)conn.Execute(emr); foreach ( var responseItem in emResponse.Responses.Where(responseItem => responseItem.Fault != null)) { DisplayFault(emr.Requests[responseItem.RequestIndex], responseItem.RequestIndex, responseItem.Fault); } } catch (Exception ex) { Console.WriteLine($"Exception during ExecuteMultiple: {ex.Message}"); throw; } emr = null; } } }
public static void Should_Execute_Subsequent_Requests_In_Order() { var context = new XrmFakedContext(); var service = context.GetFakedOrganizationService(); var account1 = new Account { Id = Guid.NewGuid(), Name = "Acc1" }; var account2 = new Account { Id = Guid.NewGuid(), Name = "Acc2" }; var executeMultipleRequest = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ReturnResponses = true }, Requests = new OrganizationRequestCollection { new CreateRequest { Target = account1 }, new CreateRequest { Target = account2 }, new UpdateRequest { Target = new Account { Id = account1.Id, Name = "Acc1 - Updated" } }, new UpdateRequest { Target = new Account { Id = account2.Id, Name = "Acc2 - Updated" } } } }; var response = service.Execute(executeMultipleRequest) as ExecuteMultipleResponse; Assert.False(response.IsFaulted); Assert.NotEmpty(response.Responses); var acc1 = service.Retrieve(Account.EntityLogicalName, account1.Id, new ColumnSet(true)).ToEntity <Account>(); Assert.NotNull(acc1); var acc2 = (service.Retrieve(Account.EntityLogicalName, account2.Id, new ColumnSet(true))).ToEntity <Account>(); Assert.NotNull(acc2); Assert.Equal("Acc1 - Updated", acc1.Name); Assert.Equal("Acc2 - Updated", acc2.Name); }
protected override void Execute(CodeActivityContext executionContext) { //Create the tracing service ITracingService tracingService = executionContext.GetExtension <ITracingService>(); //Create the context IWorkflowContext context = executionContext.GetExtension <IWorkflowContext>(); IOrganizationServiceFactory serviceFactory = executionContext.GetExtension <IOrganizationServiceFactory>(); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); EntityReference mortgageref = Mortgage.Get(executionContext); Entity mortgage = service.Retrieve(mortgageref.LogicalName, mortgageref.Id, new ColumnSet("modifiedon", "rev_mortgageterm", "rev_mortgagepayment")); RetrieveAttributeRequest retrieveAttrReq = new RetrieveAttributeRequest { EntityLogicalName = "rev_mortgage", LogicalName = "rev_mortgageterm", RetrieveAsIfPublished = true }; RetrieveAttributeResponse retrieveAttrRes = (RetrieveAttributeResponse)service.Execute(retrieveAttrReq); PicklistAttributeMetadata metadata = (PicklistAttributeMetadata)retrieveAttrRes.AttributeMetadata; OptionMetadata[] optionList = metadata.OptionSet.Options.ToArray(); string selectedOptionLabel = string.Empty; foreach (OptionMetadata oMD in optionList) { if (oMD.Value == int.Parse(((OptionSetValue)mortgage.Attributes["rev_mortgageterm"]).Value.ToString())) { selectedOptionLabel = oMD.Label.UserLocalizedLabel.Label; } } ExecuteMultipleRequest execMultReq = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings() { ContinueOnError = false, ReturnResponses = true }, Requests = new OrganizationRequestCollection() }; DateTime dueDate = ((DateTime)mortgage.Attributes["modifiedon"]).AddMonths(1); for (int i = 1; i <= int.Parse(selectedOptionLabel) * 12; ++i) { Entity mortgagepaymentrecord = new Entity("rev_mortgagepaymentrecord"); mortgagepaymentrecord.Attributes.Add("rev_name", "Payment Period " + i); mortgagepaymentrecord.Attributes.Add("rev_duedate", dueDate); mortgagepaymentrecord.Attributes.Add("rev_payment", (Money)mortgage.Attributes["rev_mortgagepayment"]); mortgagepaymentrecord.Attributes.Add("rev_mortgageid", mortgageref); CreateRequest createReq = new CreateRequest { Target = mortgagepaymentrecord }; execMultReq.Requests.Add(createReq); dueDate = dueDate.AddMonths(1); } ExecuteMultipleResponse execMultRes = (ExecuteMultipleResponse)service.Execute(execMultReq); }
private ExecuteMultipleResponse ExecuteInternal(ExecuteMultipleRequest request) { var settings = request.Settings; var response = new ExecuteMultipleResponse { Results = { ["Responses"] = new ExecuteMultipleResponseItemCollection() } }; for (int i = 0; i < request.Requests.Count; i++) { var childRequest = request.Requests[i]; OrganizationServiceFault fault = null; OrganizationResponse childResponse = null; try { if (childRequest.RequestName == "ExecuteMultiple") { throw new Exception("ExecuteMultipleRequest cannot contain an ExecuteMultipleRequest"); } childResponse = ExecuteInternal((dynamic)childRequest); if (!settings.ReturnResponses) { childResponse = null; } } catch (NotImplementedException) { throw; } catch (FaultException <OrganizationServiceFault> ex) { response["IsFaulted"] = true; fault = ex.Detail; fault.ErrorDetails["CallStack"] = ex.StackTrace; if (!settings.ContinueOnError) { break; } } catch (Exception ex) { response["IsFaulted"] = true; fault = new OrganizationServiceFault { Message = ex.Message, Timestamp = DateTime.UtcNow, ErrorDetails = { ["CallStack"] = ex.StackTrace } }; if (!settings.ContinueOnError) { break; } } finally { if (childResponse != null || fault != null) { response.Responses.Add(new ExecuteMultipleResponseItem { Fault = fault, RequestIndex = i, Response = childResponse }); } } } return(response); }
private void DoTransfer(bool useBulk = false, int bulkCount = 100) { if (sourceRecords == null || targetRecords == null) { return; } var recordCount = sourceRecords.Entities.Count; var missingCount = 0; var createCount = 0; var updateCount = 0; var deleteCount = 0; var skipCount = 0; var errorCount = 0; var totalTaskCount = sourceRecords.Entities.Count; var bulk = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings { ContinueOnError = true } }; int processed = 0; // Delete the missing source records in the target environment if ((transfermode & TransferMode.Delete) == TransferMode.Delete) { //var missing = targetRecords.Entities.Select(e => e.Id).Except(sourceRecords.Entities.Select(e => e.Id)).ToArray(); var missing = targetRecords.Entities .Where(te => !sourceRecords.Entities.Any(se => te.GetAttributeValue <Guid>(relation.Entity1IntersectAttribute).Equals(se.GetAttributeValue <Guid>(relation.Entity1IntersectAttribute)) && te.GetAttributeValue <Guid>(relation.Entity2IntersectAttribute).Equals(se.GetAttributeValue <Guid>(relation.Entity2IntersectAttribute)))) .ToArray(); missingCount = missing.Length; totalTaskCount += missingCount; for (int i = 0; i < missingCount; i++) { processed++; var record = missing[i]; var entity1id = record.GetAttributeValue <Guid>(relation.Entity1IntersectAttribute); var entity2id = record.GetAttributeValue <Guid>(relation.Entity2IntersectAttribute); SetProgress(i / totalTaskCount, ""); SetStatusMessage(useBulk ? "Adding relationship {0}/{1} for deletion" : "{0}/{1}: delete record", i + 1, missingCount); if ((transfermode & TransferMode.Preview) != TransferMode.Preview) { if (useBulk) { bulk.Requests.Add(new DisassociateRequest { Target = new EntityReference(relation.Entity1LogicalName, entity1id), Relationship = new Relationship(relation.SchemaName), RelatedEntities = new EntityReferenceCollection { new EntityReference(relation.Entity2LogicalName, entity2id) } }); if (bulk.Requests.Count % bulkCount == 0 || processed == missingCount) { var bulkResponse = (ExecuteMultipleResponse)targetService.Execute(bulk); // MscrmTools (26/11/2020): Should we need to handle potential exceptions? deleteCount += bulk.Requests.Count; bulk.Requests = new OrganizationRequestCollection(); } } else { Disassociate(relation.SchemaName, relation.Entity1LogicalName, entity1id, relation.Entity2LogicalName, entity2id); deleteCount++; } } } } processed = 0; // Transfer records for (int i = 0; i < recordCount; i++) { processed++; try { var record = sourceRecords.Entities[i]; var entity1id = record.GetAttributeValue <Guid>(relation.Entity1IntersectAttribute); var entity2id = record.GetAttributeValue <Guid>(relation.Entity2IntersectAttribute); var recordexist = targetRecords.Entities.Any(e => e.GetAttributeValue <Guid>(relation.Entity1IntersectAttribute).Equals(entity1id) && e.GetAttributeValue <Guid>(relation.Entity2IntersectAttribute).Equals(entity2id)); var name = relation.SchemaName; SetProgress((i + missingCount) / totalTaskCount, "Transfering relation '{0}'...", name); if (!recordexist && ((transfermode & TransferMode.Create) == TransferMode.Create)) { // Create missing record SetStatusMessage(useBulk ? "Adding relationship {0}/{1} for creation" : "{0}/{1}: create record", i + 1, recordCount); ApplyMappings(record); if ((transfermode & TransferMode.Preview) != TransferMode.Preview) { if (useBulk) { bulk.Requests.Add(new AssociateRequest { Target = new EntityReference(relation.Entity1LogicalName, entity1id), Relationship = new Relationship(relation.SchemaName), RelatedEntities = new EntityReferenceCollection { new EntityReference(relation.Entity2LogicalName, entity2id) } }); } else { Associate(relation.SchemaName, relation.Entity1LogicalName, entity1id, relation.Entity2LogicalName, entity2id); createCount++; } } } else { SetStatusMessage("{0}/{1}: skip record", i + 1, recordCount); skipCount++; } if (useBulk) { if (bulk.Requests.Count > 0 && bulk.Requests.Count % bulkCount == 0 || processed == recordCount) { SetStatusMessage($"Processing records {processed - bulk.Requests.Count} to {processed} of {recordCount}"); var bulkResponse = (ExecuteMultipleResponse)targetService.Execute(bulk); // MscrmTools (26/11/2020): Should we need to handle potential exceptions? var errorIndexes = new List <int>(); foreach (var response in bulkResponse.Responses) { if (response.Fault != null) { errorIndexes.Add(response.RequestIndex); Messages.Add(response.Fault.Message); errorCount++; } } for (var j = 0; j < bulk.Requests.Count; j++) { if (errorIndexes.Contains(j)) { continue; } createCount++; } bulk.Requests = new OrganizationRequestCollection(); } } } catch (System.ServiceModel.FaultException <OrganizationServiceFault> error) { this.Messages.Add(error.Message); errorCount++; } } SetStatusMessage("{0} created; {1} updated; {2} deleted; {3} skipped; {4} errors", createCount, updateCount, deleteCount, skipCount, errorCount); }
static void Main(string[] args) { var organizationServiceProxy = new OrganizationServiceProxy(GetUri(), null, GetClientCredentials(), null); DataTable csvDataTable = GetCSVData(); ExecuteMultipleRequest executeMultipleRequest1 = new ExecuteMultipleRequest() { Settings = new ExecuteMultipleSettings { ContinueOnError = true, ReturnResponses = true } , Requests = new OrganizationRequestCollection() }; ExecuteMultipleRequest executeMultipleRequest2 = new ExecuteMultipleRequest() { Settings = new ExecuteMultipleSettings { ContinueOnError = true, ReturnResponses = true } , Requests = new OrganizationRequestCollection() }; int counter = 0; for (int locIndexRow = 1; locIndexRow < csvDataTable.Rows.Count; locIndexRow++) { string name = csvDataTable.Rows[locIndexRow][0].ToString(); string primaryContact = csvDataTable.Rows[locIndexRow][1].ToString(); string telephone1 = csvDataTable.Rows[locIndexRow][2].ToString(); QueryExpression queryExpression = new QueryExpression("contact"); queryExpression.ColumnSet = new ColumnSet(false); queryExpression.NoLock = true; queryExpression.TopCount = 1; queryExpression.Criteria.AddCondition("fullname", ConditionOperator.Equal, primaryContact); Entity queryResult = organizationServiceProxy.RetrieveMultiple(queryExpression).Entities.FirstOrDefault(); if (queryResult != null) { EntityReference primaryContactReference = queryResult.ToEntityReference(); Entity customEntity = CreateCustomEntity("account", name, primaryContactReference, telephone1); UpsertRequest upsertRequest = new UpsertRequest() { Target = customEntity }; if (locIndexRow % 2 == 0) { executeMultipleRequest1.Requests.Add(upsertRequest); } else { executeMultipleRequest2.Requests.Add(upsertRequest); } counter++; Console.WriteLine($"Request {counter} added"); } } Console.WriteLine("Started executing request."); Task.WaitAll(Task.Run(() => { ExecuteMultipleResponse executeMultipleResponse = (ExecuteMultipleResponse)organizationServiceProxy.Execute(executeMultipleRequest1); foreach (var response in executeMultipleResponse.Responses) { if (response.Fault != null) { Console.WriteLine(response.Fault.Message); } else { Console.WriteLine("Request1 executed done!"); } } }), Task.Run(() => { ExecuteMultipleResponse executeMultipleResponse = (ExecuteMultipleResponse)organizationServiceProxy.Execute(executeMultipleRequest2); foreach (var response in executeMultipleResponse.Responses) { if (response.Fault != null) { Console.WriteLine(response.Fault.Message); } else { Console.WriteLine("Request2 executed done!"); } } })); executeMultipleRequest1.Requests.Clear(); executeMultipleRequest2.Requests.Clear(); Console.WriteLine("Requests have been executed"); Console.ReadLine(); }
/// <summary> /// Deletes any entity records that were created for this sample. /// <param name="prompt">Indicates whether to prompt the user /// to delete the records created in this sample.</param> /// </summary> public static void DeleteRequiredRecords(CrmServiceClient service, bool prompt) { bool deleteRecords = true; if (prompt) { Console.WriteLine("\nDo you want to delete the account record? (y/n) [y]: "); String answer = Console.ReadLine(); deleteRecords = (answer.StartsWith("y") || answer.StartsWith("Y") || answer == String.Empty); } if (!deleteRecords) { return; } var requestWithNoResults = new ExecuteMultipleRequest() { // Set the execution behavior to not continue after the first error is received // and to not return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = false, ReturnResponses = false }, Requests = new OrganizationRequestCollection() }; // Update the entities that were previously created. EntityCollection delete = GetCollectionOfEntitiesToDelete(); foreach (var entity in delete.Entities) { DeleteRequest deleteRequest = new DeleteRequest { Target = entity.ToEntityReference() }; requestWithNoResults.Requests.Add(deleteRequest); } var responseWithNoResults = (ExecuteMultipleResponse)service.Execute(requestWithNoResults); // 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 (responseWithNoResults.Responses.Count > 0) { foreach (var responseItem in responseWithNoResults.Responses) { if (responseItem.Fault != null) { DisplayFault(requestWithNoResults.Requests[responseItem.RequestIndex], responseItem.RequestIndex, responseItem.Fault); } } } else { Console.WriteLine("All account records have been deleted successfully."); } }
private void ExecuteMultipleUpdates(List<Tuple<Guid, string, byte[]>> imagesToUpdate, ExecuteMultipleRequest executeMultipleRequests) { var executeMultipleResponses = (ExecuteMultipleResponse)Service.Execute(executeMultipleRequests); foreach (var executeMultipleResponse in executeMultipleResponses.Responses) { var updateResponse = (UpdateResponse)executeMultipleResponse.Response; if (executeMultipleResponse.Fault != null) imagesToUpdate.RemoveAll(x => x.Item1 == ((UpdateRequest)executeMultipleRequests.Requests[executeMultipleResponse.RequestIndex]).Target.Id); } }
/// <summary> /// Retrive data from sql into dataset and upload on created custom entity. /// </summary> /// <param name="serverConfig"></param> /// <param name="schemas"></param> public string uploadData(DataSet dss, string CRM_Table, string Suffix) { string a = null; int x = 0; string prefix = "new_"; customEntityName = prefix + CRM_Table + Suffix; ExecuteMultipleRequest UploadMulti = null; //Generate Multiple Request. //Set setting for multiple Request.Continue on error & Return Responses UploadMulti = new ExecuteMultipleRequest() { Settings = new ExecuteMultipleSettings() { ContinueOnError = false, ReturnResponses = true }, //create request collection. Requests = new OrganizationRequestCollection() }; ExecuteMultipleResponse responseWithResults; // This statement is required to enable early-bound type support. using (SqlConnection cnn = new SqlConnection("Data Source=" + SQL_IP + "," + SQL_Port + ";user="******";password="******";database=" + SQL_DB + "; ")) { SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM [" + SQL_TableName + "]", cnn); //Fetch data from table SQL_TableName. DataSet ds = new DataSet(); da.Fill(ds, SQL_TableName); //Fill Data into DataSet ds. foreach (DataRow row in ds.Tables[SQL_TableName].Rows) { Entity Merc = new Entity(customEntityName); //Create Entity which is type of customEntity. int i = 0, f = 0; foreach (DataRow roww in dss.Tables[SQL_TableName].Rows) //Dynamically Mapping data to there relative Fields { string t = prefix + roww[0].ToString() + Suffix; switch (roww[1].ToString()) { case "nvarchar": case "text": Merc[t.ToLower()] = row[i].ToString(); i++; break; case "datetime": // a= DateTime.Parse(row[i].ToString()).ToUniversalTime().ToString(); //Merc[schemas[i].ToLower()] = DateTime.Parse(row[i].ToString()); Merc[t.ToLower()] = row[i].ToString(); i++; break; case "smalldatetime": // Merc[schemas[i].ToLower()] = DateTime.Parse(row[i].ToString()); Merc[t.ToLower()] = row[i].ToString(); i++; break; case "int": Merc[t.ToLower()] = Convert.ToInt32(row[i]); i++; break; case "money": Merc[t.ToLower()] = new Money(Convert.ToDecimal(row[i].ToString())); i++; break; case "decimal": Merc[t.ToLower()] = row[i]; i++; break; } } // Add a CreateRequest for each entity to the request collection. CreateRequest createRequest = new CreateRequest { Target = Merc }; UploadMulti.Requests.Add(createRequest);//Add Request to varibale UploadMulti f++; if (UploadMulti.Requests.Count == 1000) //if 1000 records are added than execute request. { _serviceProxy.Timeout = new TimeSpan(0, 10, 0); //set 10 min timout for executing multiple request responseWithResults = (ExecuteMultipleResponse)_service.Execute(UploadMulti); x = x + responseWithResults.Responses.Count; UploadMulti.Requests.Clear();//Clear all request from UploadMulti. f = 0; } } if (UploadMulti.Requests.Count > 0) { responseWithResults = (ExecuteMultipleResponse)_service.Execute(UploadMulti); x = x + responseWithResults.Responses.Count; UploadMulti.Requests.Clear(); } a = "DataUpload" + x; } return(a); }
private void ExecuteExecuteMultipleRequest(OrganizationService organizationService, ExecuteMultipleRequest executeMultipleRequest) { executeMultipleRequest.Settings = new ExecuteMultipleSettings { ContinueOnError = true, ReturnResponses = true }; var organizationResponse = (ExecuteMultipleResponse) organizationService.Execute(executeMultipleRequest); if (organizationResponse == null || organizationResponse.Responses == null) { errorList.Add(new Exception("Failed to get response for ExecuteMultipleOperation.")); return; } foreach (var responseItem in organizationResponse.Responses) { if (responseItem.Fault != null) { var index = responseItem.RequestIndex; var schemaName = ((CreateAttributeRequest) executeMultipleRequest.Requests[index]).Attribute.SchemaName; var errorMessage = string.Format( "An error occured while creating the attribute: {0}. Detailed error:\n{1}", schemaName, responseItem.Fault.ToErrorString()); if (responseItem.Fault.ErrorCode == -2147192813) { warningList.Add(new Exception(errorMessage)); } else { errorList.Add(new Exception(errorMessage)); } } } }
///<summary> ///Create Custom Entity. ///</summary> public List <string> createCustomEntity(DataSet ds, string CRM_TableName, string CRM_Suffix) { List <string> lst = new List <string>(); String prefix = "new_"; ExecuteMultipleRequest SchemaCreate = null; customEntityName = prefix + CRM_TableName.ToLower() + CRM_Suffix; SchemaCreate = 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() }; int f = 1; foreach (DataRow row in ds.Tables[SQL_TableName].Rows) { string t = prefix + row[0].ToString() + CRM_Suffix; //add Prifix & Suffix for creating Entity and it's attributes. lst.Add(t); //Add Attributes name in List for use it further in insertion of data into these entities. if (f > 0) //Set flag for first create Custom Entity than create attribute of it. { CreateEntityRequest request = new CreateEntityRequest { HasNotes = true, HasActivities = false, Entity = new EntityMetadata { IsActivity = false, SchemaName = customEntityName, DisplayName = new Label(CRM_TableName, 1033), DisplayCollectionName = new Label(CRM_TableName, 1033), OwnershipType = OwnershipTypes.UserOwned, IsAvailableOffline = true, }, PrimaryAttribute = new StringAttributeMetadata //create primary attribute, string type. { SchemaName = t, RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None), MaxLength = 200, DisplayName = new Label(row[0].ToString(), 1033), Description = new Label(row[0].ToString(), 1033) } }; _service.Execute(request);//Execute Request for create Entity. f--; continue; } switch (row[1].ToString()) //Use Switch case for Dynamically Create Attributes accourding to there data types in SQL schema fields. { case "nvarchar": case "text": CreateAttributeRequest M_ID = new CreateAttributeRequest { EntityName = customEntityName, Attribute = new StringAttributeMetadata { SchemaName = t, RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None), MaxLength = 2000, Format = StringFormat.Text, DisplayName = new Label(row[0].ToString(), 1033), Description = new Label(row[0].ToString(), 1033) } }; SchemaCreate.Requests.Add(M_ID); //Add Request to MultipleRequest. break; case "datetime": CreateAttributeRequest M_CreatedDate = new CreateAttributeRequest { EntityName = customEntityName, //DateTimeAttributeMetadata Attribute = new StringAttributeMetadata { SchemaName = t, RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None), //Format = DateTimeFormat.DateAndTime, //DateTimeBehavior =DateTimeBehavior.UserLocal, MaxLength = 50, Format = StringFormat.Text, DisplayName = new Label(row[0].ToString(), 1033), Description = new Label(row[0].ToString(), 1033) } }; SchemaCreate.Requests.Add(M_CreatedDate); // _service.Execute(M_CreatedDate); break; case "smalldatetime": CreateAttributeRequest M_CreatedSmallDate = new CreateAttributeRequest { EntityName = customEntityName, //DateTimeAttributeMetadata Attribute = new StringAttributeMetadata { SchemaName = t, RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None), //Format = DateTimeFormat.DateOnly, //DateTimeBehavior = DateTimeBehavior.DateOnly, MaxLength = 2000, Format = StringFormat.Text, DisplayName = new Label(row[0].ToString(), 1033), Description = new Label(row[0].ToString(), 1033) } }; SchemaCreate.Requests.Add(M_CreatedSmallDate); //_service.Execute(M_CreatedSmallDate); break; case "int": CreateAttributeRequest M_Integer = new CreateAttributeRequest { EntityName = customEntityName, Attribute = new IntegerAttributeMetadata { SchemaName = t, RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None), DisplayName = new Label(row[0].ToString(), 1033), Description = new Label(row[0].ToString(), 1033) } }; SchemaCreate.Requests.Add(M_Integer); //_service.Execute(M_Integer); break; case "money": CreateAttributeRequest createBalanceAttributeRequest = new CreateAttributeRequest { EntityName = customEntityName, Attribute = new MoneyAttributeMetadata { SchemaName = t, RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None), Precision = 1, DisplayName = new Label(row[0].ToString(), 1033), Description = new Label(row[0].ToString(), 1033), } }; SchemaCreate.Requests.Add(createBalanceAttributeRequest); // _service.Execute(createBalanceAttributeRequest); break; case "decimal": CreateAttributeRequest M_Decimal = new CreateAttributeRequest { EntityName = customEntityName, Attribute = new DecimalAttributeMetadata { SchemaName = t, RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None), DisplayName = new Label(row[0].ToString(), 1033), Description = new Label(row[0].ToString(), 1033), } }; SchemaCreate.Requests.Add(M_Decimal); // _service.Execute(M_Decimal); break; } } _serviceProxy.Timeout = new TimeSpan(0, 10, 0); //Set 10min Timeout for response MultipleRequest. ExecuteMultipleResponse responseWithResults = (ExecuteMultipleResponse)_service.Execute(SchemaCreate); //Execute Multiple Request to create all attributes return(lst); }
private void ExecuteMultipleWebresourceRequests(ExecuteMultipleRequest request) { try { var organizationService = GetSharedOrganizationService(); ExecuteExecuteMultipleRequest(organizationService, request); } catch (Exception ex) { var exception = new Exception("Error occured while creating webresources", ex); errorList.Add(exception); } }
private void UpdateWebResources(List<WebResourceItem> items) { //TODO: Handle CRM 2011 w/o execute multiple ExecuteMultipleRequest emRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings { ContinueOnError = false, ReturnResponses = true } }; OrganizationRequestCollection requests = new OrganizationRequestCollection(); string projectName = ((ComboBoxItem)Projects.SelectedItem).Content.ToString(); Project project = GetProjectByName(projectName); if (project == null) return; string publishXml = "<importexportxml><webresources>"; foreach (var webResourceItem in items) { Entity webResource = new Entity("webresource") { Id = webResourceItem.WebResourceId }; string filePath = Path.GetDirectoryName(project.FullName) + webResourceItem.BoundFile.Replace("/", "\\"); if (!File.Exists(filePath)) continue; string content = File.ReadAllText(filePath); webResource["content"] = EncodeString(content); UpdateRequest request = new UpdateRequest { Target = webResource }; requests.Add(request); publishXml += "<webresource>{" + webResource.Id + "}</webresource>"; } publishXml += "</webresources></importexportxml>"; PublishXmlRequest pubRequest = new PublishXmlRequest { ParameterXml = publishXml }; requests.Add(pubRequest); emRequest.Requests = requests; string connString = ((CrmConn)Connections.SelectedItem).ConnectionString; CrmConnection connection = CrmConnection.Parse(connString); using (OrganizationService orgService = new OrganizationService(connection)) { DisplayStatusMessage("Updating & publishing web resources"); ExecuteMultipleResponse emResponse = (ExecuteMultipleResponse)orgService.Execute(emRequest); foreach (var responseItem in emResponse.Responses) { if (responseItem.Fault == null) continue; //Some error - do something //TODO: handle error DisplayStatusMessage(String.Empty); return; } MessageBox.Show("Published");//change to status message that goes away itself DisplayStatusMessage(String.Empty); } }
public static void Should_Not_Continue_On_Error_If_Not_Told_To_Do_So() { var context = new XrmFakedContext(); var service = context.GetFakedOrganizationService(); var account1 = new Account { Id = Guid.NewGuid(), Name = "Acc1" }; var account2 = new Account { Id = account1.Id, Name = "Acc2 - Same ID as Acc 1" }; var account3 = new Account { Id = Guid.NewGuid(), Name = "Acc3" }; var executeMultipleRequest = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings { ReturnResponses = true, ContinueOnError = false }, Requests = new OrganizationRequestCollection { new CreateRequest { Target = account1 }, new CreateRequest { Target = account2 }, new CreateRequest { Target = account3 } } }; var response = service.Execute(executeMultipleRequest) as ExecuteMultipleResponse; Assert.True(response.IsFaulted); Assert.NotEmpty(response.Responses); Assert.True(response.Responses.Any(resp => resp.Fault != null)); Assert.NotNull(service.Retrieve(Account.EntityLogicalName, account1.Id, new ColumnSet(true))); Assert.Throws<FaultException<OrganizationServiceFault>>(() => service.Retrieve(Account.EntityLogicalName, account3.Id, new ColumnSet(true))); }
/// <summary> /// Deletes any entity records that were created for this sample. /// <param name="prompt">Indicates whether to prompt the user /// to delete the records created in this sample.</param> /// </summary> public void DeleteRequiredRecords(bool prompt) { bool deleteRecords = true; if (prompt) { Console.WriteLine("\nDo you want to delete the account record? (y/n) [y]: "); String answer = Console.ReadLine(); deleteRecords = (answer.StartsWith("y") || answer.StartsWith("Y") || answer == String.Empty); } if (!deleteRecords) return; ExecuteMultipleRequest requestWithNoResults = new ExecuteMultipleRequest() { // Set the execution behavior to not continue after the first error is received // and to not return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = false, ReturnResponses = false }, Requests = new OrganizationRequestCollection() }; // Update the entities that were previously created. EntityCollection delete = GetCollectionOfEntitiesToDelete(); foreach (var entity in delete.Entities) { DeleteRequest deleteRequest = new DeleteRequest { Target = entity.ToEntityReference() }; requestWithNoResults.Requests.Add(deleteRequest); } ExecuteMultipleResponse responseWithNoResults = (ExecuteMultipleResponse)_serviceProxy.Execute(requestWithNoResults); // 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 (responseWithNoResults.Responses.Count > 0) { foreach (var responseItem in responseWithNoResults.Responses) { if (responseItem.Fault != null) DisplayFault(requestWithNoResults.Requests[responseItem.RequestIndex], responseItem.RequestIndex, responseItem.Fault); } } else { Console.WriteLine("All account records have been deleted successfully."); } }