'Dynamics 365 Duplicate Detection Plugin on Subgrid Record create
hope someone can help me I am been struggling with this for a few hours now.
I am creating a Plugin to Create a custom entity record called Future Products(Entity B) on a Subgrid of an EntityA record(Case).
EntityA is Case that has a 1:N relationship with custom EntityB. Entity B also has an M:1 relationship with Entity C(Product Category).
In total there are 3 entities, Case, Future Products, and the last Product Category.
My plugin is registered on creation of EntityB, which has many to one Case(Entity A).
The plugin needs to detect duplicate records added to the SubGrid which is on Case(Entity A), however, the records sit on Entity B(future products).
My challenge is that EntityB has a field called product category, which is a lookup to EntityC, I want to compare the value in the context user is adding to the list already on Case, and if there is a match with the same lookup name, then throw a new error to say it detected duplicate record being added.
My code is not working, and an exception is hit when adding any Product Category and not on the duplicate found.
See c# plugin code below
// 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 entity = (Entity)context.InputParameters["Target"];
// Obtain the organization service reference which you will need for
// web service calls.
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService organizationService = serviceFactory.CreateOrganizationService(context.UserId);
try
{
if (entity.Contains("mm_application"))
{
tracingService.Trace($"Application Case- {(EntityReference)entity["mm_application"]}");
var query = new QueryExpression("mm_futureproductcategories");
query.ColumnSet.AddColumns("mm_application", "mm_productcategory");
//Get contect Entity ID
Entity futureProductRecord = organizationService.Retrieve(entity.LogicalName, entity.Id, new ColumnSet(true));
//Get Related Case application lookup
EntityReference relatedCase = futureProductRecord.GetAttributeValue<EntityReference>("mm_application");
Entity caseRecord = organizationService.Retrieve("incident", relatedCase.Id, new ColumnSet(true));
//Get Related Product Category lookup
EntityReference relatedProductCategory = futureProductRecord.GetAttributeValue<EntityReference>("mm_productcategory");
Entity productCategoryRecord = organizationService.Retrieve("mm_productcategory", relatedProductCategory.Id, new ColumnSet(true));
query.Criteria.AddCondition("mm_application", ConditionOperator.Equal, caseRecord.Id);
query.Criteria.AddCondition("mm_productcategory", ConditionOperator.Equal, productCategoryRecord.Id);
EntityCollection futureProductCatRecords = organizationService.RetrieveMultiple(query);
if (futureProductCatRecords.Entities.Count > 0)
{
throw new InvalidPluginExecutionException($"Duplicate Future Product Category detected.");
}
}
}
The plugin always hits the exception, even when Future Products Category added is not already in the subgrid on the case records. I may be missing something, please help if you can I have struggled with this for the whole day now.
Solution 1:[1]
I ended up figuring it out, with the help of some more googling, So my above code was incorrect, and also it was running on Post Operation Create instead of Pre Operation.
I solved it by getting the lookup values from the entity which is already in the context of the plugin. See my updated code on how to check duplicates on a Subgrid create.
try
{
if (entity.Contains("mm_productcategory"))
{
tracingService.Trace($"Application Case- {(EntityReference)entity["mm_application"]}");
// Instantiate QueryExpression query
var query = new QueryExpression("mm_futureproductcategories");
// Add columns to query.ColumnSet
query.ColumnSet.AddColumns("mm_application", "mm_productcategory");
// Define filter query.Criteria
if (entity.Contains("mm_productcategory"))
{
tracingService.Trace($"Application Case- {(EntityReference)entity["mm_productcategory"]}");
query.Criteria.AddCondition("mm_productcategory", ConditionOperator.Equal, entity.GetAttributeValue<EntityReference>("mm_productcategory").Id);
}
if (entity.Contains("mm_application"))
{
query.Criteria.AddCondition("mm_application", ConditionOperator.Equal, entity.GetAttributeValue<EntityReference>("mm_application").Id);
}
EntityCollection futureProductCatRecords = organizationService.RetrieveMultiple(query);
if (futureProductCatRecords.Entities.Count > 0)
{
throw new InvalidPluginExecutionException($"Duplicate Future Product Category detected.");
}
}
}
This code will check if there are any duplicate Future Products and then throw an exception if one is found.
Solution 2:[2]
For this to work, you need to check that the current record isn't returned.
You need to add the line:
query.Criteria.AddCondition(mm_futureproductcategories, ConditionOperator.NotEqual, futureProductRecord.Id);
Or you could just change your final condition to:
if (futureProductCarRecords.Entities.Count > 1){}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Papi |
| Solution 2 | halfer |
