fake-xrm-easy icon indicating copy to clipboard operation
fake-xrm-easy copied to clipboard

Query on associatedentitytypecode should work with both Entity Name and ObjectTypeCode

Open bwmodular opened this issue 2 years ago • 5 comments

Describe the bug When you query the documenttemplate table in CRM, and you add a filter on the 'associatedentitytypecode' column, you can pass this either as an integer (the objecttypecode) or as a string (the table name). When you perform the same query against fakeXrmEasy, it fails if you pass in the object type code, as it tries to perform the string method 'ToLowerInvariant' on the integer.

This is the error: Method 'System.String ToLowerInvariant()' declared on type 'System.String' cannot be called with instance of type 'System.Int32'

To Reproduce Here's code that will work in Dynamics 365 online (sorry couldn't get github to format it better): void Main() { IOrganizationService service = MyExtensions.ConnectToCrm(MyExtensions.Environments.BLAH_DEV); GetTemplateWithEntityName(service).Dump("Query with entity Name"); GetTemplateWithEntityTypeCode(service).Dump("Query with ObjectTypeCode"); }

Guid GetTemplateWithEntityTypeCode(IOrganizationService service) { QueryExpression query = new QueryExpression("documenttemplate"); query.Criteria.AddCondition("name", ConditionOperator.Equal, "Order Summary"); //query.Criteria.AddCondition("associatedentitytypecode", ConditionOperator.Equal, "salesorder"); query.Criteria.AddCondition("associatedentitytypecode", ConditionOperator.Equal, 1088);

EntityCollection templates = service.RetrieveMultiple(query);		
return templates.Entities[0].Id;

}

Guid GetTemplateWithEntityName(IOrganizationService service) { QueryExpression query = new QueryExpression("documenttemplate"); query.Criteria.AddCondition("name", ConditionOperator.Equal, "Order Summary"); query.Criteria.AddCondition("associatedentitytypecode", ConditionOperator.Equal, "salesorder"); //query.Criteria.AddCondition("associatedentitytypecode", ConditionOperator.Equal, 1088);

EntityCollection templates = service.RetrieveMultiple(query);

return templates.Entities[0].Id;

} ...and here's similar code which fails in fakeXrmEasy:

void Main() { XrmFakedContext fakedContext = new XrmFakedContext(); IOrganizationService service = fakedContext.GetOrganizationService(); DocumentTemplate documentTemplate = new DocumentTemplate() { Id = Guid.NewGuid(), Name = "Order Summary", AssociatedEntityTypeCode = "salesorder", Status = false }; fakedContext.Initialize(new List<Entity> { documentTemplate });

GetTemplateWithEntityName(service).Dump("Query with entity Name");
GetTemplateWithEntityTypeCode(service).Dump("Query with ObjectTypeCode");	

}

Guid GetTemplateWithEntityTypeCode(IOrganizationService service) { QueryExpression query = new QueryExpression("documenttemplate"); query.Criteria.AddCondition("name", ConditionOperator.Equal, "Order Summary"); //query.Criteria.AddCondition("associatedentitytypecode", ConditionOperator.Equal, "salesorder"); query.Criteria.AddCondition("associatedentitytypecode", ConditionOperator.Equal, 1088);

EntityCollection templates = service.RetrieveMultiple(query);
return templates.Entities[0].Id;

}

Guid GetTemplateWithEntityName(IOrganizationService service) { QueryExpression query = new QueryExpression("documenttemplate"); query.Criteria.AddCondition("name", ConditionOperator.Equal, "Order Summary"); query.Criteria.AddCondition("associatedentitytypecode", ConditionOperator.Equal, "salesorder"); //query.Criteria.AddCondition("associatedentitytypecode", ConditionOperator.Equal, 1088);

EntityCollection templates = service.RetrieveMultiple(query);

return templates.Entities[0].Id;

}

** FakeXrmEasy and Dynamics 365 / CRM version ** Version 9 of FakeXrmEasy, v 1.57.1, Dynamics 365 online Screenshots If applicable, add screenshots to help explain your problem. Working in 'real' instance image Not working in tests image

Not a showstopper, but a definite difference between D365 online and FakeXrmEasy...

bwmodular avatar Jul 15 '21 13:07 bwmodular

Thanks for raising this Ben.

What is the type of associatedentitytypecode property that is generated? I'm wondering if using fake metadata to declare it as an integer will solve it for the time being...

jordimontana82 avatar Jul 15 '21 16:07 jordimontana82

Hi Jordi It's a string: image How would I fake the metadata as a workaround for now?

bwmodular avatar Jul 15 '21 22:07 bwmodular

I'm guessing this will have to be resolved in the condition expression evaluation. We could try and convert values to their string representation if the associated type was a string and the value wasn't a string already. It would allow then to use the object type code like:

DocumentTemplate documentTemplate = new DocumentTemplate() { Id = Guid.NewGuid(), Name = "Order Summary", AssociatedEntityTypeCode = "1088", Status = false };

Right now, in order to make it work, the QueryExpression will have to use the object type code as a string value, i.e.

query.Criteria.AddCondition("associatedentitytypecode", ConditionOperator.Equal, "1088");

Could you try passing in the object type code as a string to see if that works against the real D365 online? If so, that might be the workaround for the time being...

jordimontana82 avatar Jul 16 '21 10:07 jordimontana82

Unfortunately, if I try and pass the entity type code as a string, I get this error: The entity with a name = '1088' with namemapping = 'Logical' was not found in the MetadataCache.

bwmodular avatar Jul 17 '21 11:07 bwmodular

Thanks Ben, so fix in query translation so....

jordimontana82 avatar Jul 23 '21 07:07 jordimontana82