I have Entity A and Entity B related via 1:N.
There will usually be 1 or more Entity B records hanging off of a particular Entity A record.
Every time I deactivate an Entity B record, I need a workflow to run that checks and counts the number of inactive Entity B records related to the same Entity A that the deactivated Entity B record that was just deactivated.
The workflow should also check and count the number of Active Entity B records related to entity A.
Once it has the counts, there are other steps in the workflow that perform a number of operations on a number of things based on those counts.
The problem is the counts are not coming back correctly.
To do the actual counts, I use the following fetch xml query - which searches for and counts the number of inactive related records that hang off the same Entity A parent via 1:N relationship.
The other etch xml query searches for active related records that hang a 1:N relationship.
When running inside the custom workflow activity, the data returned is errant. I get 0 active and 0 inactive which is wrong.
In the example I am using here, after deactivating an Entity B child and since this particular parent has only that child record on it, the expected result is 0 active and 1 inactive.
I get that result if I use fetchxml via xrmtoolbox, but not in the custom workflow activity.
Everything is working except for the active and inactive counts.
In the screen shot below, when I deactivated the child record, the custom workflow activity should run and see that there is 0 active and 1 inactive but it does not. It sees 0 active and 0 inactive.
I have some trace-logging enabled and this is what is in the log.
Custom Workflow Activity Started. User ID: 009284ef-7b36-e811-a972-000d3a1a7a9b Primary Entity ID: 2be5642b-6e7c-eb11-a812-000d3a8bd140 Primary Entity Name: cpp_transfercriteria URL parser completed successfully At End of Main CodeActivityContext. Inactive Count: 0 Active Count: 0
What on earth am I missing that the Inactive count is not 1 when there is clearly one inactive child record?
I've included the custom workflow activity code below. Any help would be greatly appreciated.
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Linq; using System.Text; using System.ServiceModel; using System.Threading.Tasks; using System.Activities; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Workflow; using System.Runtime.Serialization; using Microsoft.Xrm.Sdk.Query; namespace ACECountRecordsWKF { public abstract class ACECountRecordsWKF : CodeActivity { public sealed class LocalWorkflowContext { internal IServiceProvider ServiceProvider { get; private set; } internal IOrganizationService OrganizationService { get; private set; } internal IWorkflowContext WorkflowExecutionContext { get; private set; } internal ITracingService TracingService { get; private set; } private LocalWorkflowContext() { } internal LocalWorkflowContext(CodeActivityContext executionContext) { if (executionContext == null) { throw new ArgumentNullException("serviceProvider"); } // Obtain the execution context service from the service provider. this.WorkflowExecutionContext = (IWorkflowContext)executionContext.GetExtension(); // Obtain the tracing service from the service provider. this.TracingService = (ITracingService)executionContext.GetExtension(); // Obtain the Organization Service factory service from the service provider IOrganizationServiceFactory factory = (IOrganizationServiceFactory)executionContext.GetExtension(); // Use the factory to generate the Organization Service. this.OrganizationService = factory.CreateOrganizationService(this.WorkflowExecutionContext.UserId); } internal void Trace(string message) { if (string.IsNullOrWhiteSpace(message) || this.TracingService == null) { return; } if (this.WorkflowExecutionContext == null) { this.TracingService.Trace(message); } else { this.TracingService.Trace( "{0}, Correlation Id: {1}, Initiating User: {2}", message, this.WorkflowExecutionContext.CorrelationId, this.WorkflowExecutionContext.InitiatingUserId); } } } } public abstract class FetchWF : CodeActivity { protected FetchExpression ActiveRecordQuery; protected FetchExpression InactiveRecordQuery; protected IOrganizationService service; protected override void Execute(CodeActivityContext executionContext) { ITracingService tracingService = executionContext.GetExtension(); tracingService.Trace("Custom Workflow Activity Started."); if (executionContext == null) { throw new ArgumentNullException("serviceProvider"); } // Construct the Local plug-in context. var context = executionContext.GetExtension(); var servicefactory = executionContext.GetExtension(); service = servicefactory.CreateOrganizationService(context.UserId); tracingService.Trace("User ID: " context.UserId); var CurrentEntityID = context.PrimaryEntityId; tracingService.Trace("Primary Entity ID: " context.PrimaryEntityId); var entityLogicalName = context.PrimaryEntityName; tracingService.Trace("Primary Entity Name: " context.PrimaryEntityName); //var userId = context.InitiatingUserId; var entityReference = new DynamicUrlParser(RecordUrl.Get(executionContext)); tracingService.Trace("URL parser completed successfully"); string fetchActive = QueryForActiveRecords.Get(executionContext); fetchActive = String.Format(fetchActive, entityReference.ToString()); ActiveRecordQuery = new FetchExpression(fetchActive); string fetchInActive = QueryForInactiveRecords.Get(executionContext); fetchInActive = String.Format(fetchInActive, entityReference.ToString()); InactiveRecordQuery = new FetchExpression(fetchInActive); tracingService.Trace("At End of Main CodeActivityContext."); } [Input("Record Dynamic Url")] [RequiredArgument] public InArgument RecordUrl { get; set; } [Input("QueryForActiveRecords")] public InArgument QueryForActiveRecords { get; set; } [Input("QueryForInactiveRecords")] public InArgument QueryForInactiveRecords { get; set; } } public class FetchWFCountResult : FetchWF { protected override void Execute(CodeActivityContext executionContext) { ITracingService tracingService = executionContext.GetExtension(); base.Execute(executionContext); var x = service.RetrieveMultiple(InactiveRecordQuery).Entities.Count; tracingService.Trace("Inactivae Count: " x); var y = service.RetrieveMultiple(ActiveRecordQuery).Entities.Count; tracingService.Trace("Acctivae Count: " y); if (service.RetrieveMultiple(InactiveRecordQuery).Entities.Count > 0) { tracingService.Trace("Inside top level if where Inactive Record Query Count > 0"); InactiveRecordCount.Set(executionContext, service.RetrieveMultiple(InactiveRecordQuery).Entities.Count); if (service.RetrieveMultiple(ActiveRecordQuery).Entities.Count > 0) { tracingService.Trace("Inside Mid level if where Active Record Query Count > 0"); tracingService.Trace("ActiveRecordCount Value is: " service.RetrieveMultiple(ActiveRecordQuery).Entities.Count); ActiveRecordCount.Set(executionContext, service.RetrieveMultiple(ActiveRecordQuery).Entities.Count); } } else { ActiveRecordCount.Set(executionContext, 0); tracingService.Trace("Set Default ActiveRecordCount to 0."); InactiveRecordCount.Set(executionContext, 0); tracingService.Trace("Set Default InactiveRecordCount to 0."); } } [Output("ActiveRecordCount")] public OutArgument ActiveRecordCount { get; set; } [Output("InactiveRecordCount")] public OutArgument InactiveRecordCount { get; set; } }