Search code examples
dynamics-crmdynamics-365common-data-service

CrmServiceClient.GetEntityMetadata returns wrong information


Using the Microsoft.CrmSdk assembly to generate entities in Dynamics 365 for Customer Engagement (version 9), I found out that the method GetEntityMetadata from CrmServiceClient does not get the most uptodate information from entities.

Here the code to show you:

using (var svc = new CrmServiceClient(strConn))
{
    EntityMetadata em = svc.GetEntityMetadata(PREFIX + TABLE_NAME_D, EntityFilters.Attributes);
    if (em == null)
    {
        Console.WriteLine($"Create entity [{PREFIX + TABLE_NAME_D}]");
        CreateEntityRequest createRequest = new CreateEntityRequest
        {
            Entity = new EntityMetadata
            {
                SchemaName = PREFIX + TABLE_NAME_D,
                LogicalName = PREFIX + TABLE_NAME_D,
                DisplayName = new Label(TABLE_LABEL, 1036),
                DisplayCollectionName = new Label(TABLE_LABEL_P, 1036),
                OwnershipType = OwnershipTypes.UserOwned,
            },
            PrimaryAttribute = new StringAttributeMetadata
            {
                SchemaName = PREFIX + "name",
                MaxLength = 30,
                FormatName = StringFormatName.Text,
                DisplayName = new Label("Residence", 1036),
            }
        };
        CreateEntityResponse resp = (CreateEntityResponse)svc.Execute(createRequest);
        em = svc.GetEntityMetadata(PREFIX + TABLE_NAME_D, EntityFilters.All);
        // At this point, em is null!!!
    }
}

After the createResponse is received, the entity is well created in Dynamics, but still the GetEntityMetadata called just after is still null. If I wait a few seconds and make another call, the response is now correct. But that's horrible! Is there any way to "force" the refresh of the response? Thanks.


Solution

  • Ok I found it! It's linked to a caching mechanism. One must use the function ResetLocalMetadataCache to clean the cache, but there seems to be an issue with this function. It will only works by passing the entity name in parameter (if you call it without parameter, it is supposed to clean the entire cache but that does not work for me).

        EntityMetadata em = svc.GetEntityMetadata(TABLE_NAME_D, EntityFilters.All); // Request sent
        em = svc.GetEntityMetadata(TABLE_NAME_D, EntityFilters.All); // Cache used
        svc.ResetLocalMetadataCache(); // No effect?!
        em = svc.GetEntityMetadata(TABLE_NAME_D, EntityFilters.All); // Cache used
        em = svc.GetEntityMetadata(TABLE_NAME_D, EntityFilters.All); // Cache used
        svc.ResetLocalMetadataCache(TABLE_NAME_D); // Cache cleaned for this entity
        em = svc.GetEntityMetadata(TABLE_NAME_D, EntityFilters.All); // Request sent!