2
votes

So it seems that it is a fairly common question in CRM to try get the object type code when you have an entity name. But since I always have to do things the hard way, I have the reverse task: I have the object type code, and need to get the entity name.

In general, the ultimate task is to take the the CRM regarding information on an email, and use it to query CRM for additional info. I can get the regardingID and the object type code easily. And for standard entities I can use a hardcoded lookup to get an entity name. But for custom entities, this won't work, as the object type code can be different in different organizations.

To get the regardingID and object type code:

string regardingId;
regardingId = (String)(item.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/crmRegardingId"));

dynamic crmRegardingObjectType;
crmRegardingObjectType = item.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/crmRegardingObjectType");

I could do a request to retrieve metadata for all entities & find the appropriate object type code, but this is really slow and way too much data:

RetrieveAllEntitiesRequest entitiesRequest = new RetrieveAllEntitiesRequest();
entitiesRequest.EntityFilters = EntityFilters.Entity;
RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)service.Execute(entitiesRequest);

I have to think there is a better way, but I have been stuck for a while.

ANSWER This is what I ended up doing:

        string entityLogicalName = String.Empty;

        MetadataFilterExpression EntityFilter = new MetadataFilterExpression(LogicalOperator.And);
        EntityFilter.Conditions.Add(new MetadataConditionExpression("ObjectTypeCode", MetadataConditionOperator.Equals, objectTypeCode));

        MetadataPropertiesExpression mpe = new MetadataPropertiesExpression();
        mpe.AllProperties = false;
        mpe.PropertyNames.Add("DisplayName");
        mpe.PropertyNames.Add("ObjectTypeCode");
        mpe.PropertyNames.Add("PrimaryIdAttribute");
        mpe.PropertyNames.Add("PrimaryNameAttribute");

        EntityQueryExpression entityQueryExpression = new EntityQueryExpression()
        {
            Criteria = EntityFilter,
            Properties = mpe
        };

        RetrieveMetadataChangesResponse initialRequest = GetMetadataChanges(entityQueryExpression, null, DeletedMetadataFilters.OptionSet);
        if (initialRequest.EntityMetadata.Count == 1)
        {
            entityLogicalName = initialRequest.EntityMetadata[0].LogicalName;
        }

        return entityLogicalName;

    protected RetrieveMetadataChangesResponse GetMetadataChanges(EntityQueryExpression entityQueryExpression, String clientVersionStamp, DeletedMetadataFilters deletedMetadataFilter)
    {
        RetrieveMetadataChangesRequest retrieveMetadataChangesRequest = new RetrieveMetadataChangesRequest()
        {
            Query = entityQueryExpression,
            ClientVersionStamp = clientVersionStamp,
            DeletedMetadataFilters = deletedMetadataFilter
        };

        return (RetrieveMetadataChangesResponse)organizationService.Execute(retrieveMetadataChangesRequest);
    }
1
You should really stay away from using the Object Type Code at all. The object type code is determined by the order in which the entities have been added to your version of CRM. So if you have a test environment and add A, B, and C, but then in prod add A, C and B, the type codes for B and C will be different between environment...Daryl
I agree, but that is the information that is stored in an Outlook item. It's Microsoft's choice, not mine.space ace

1 Answers

2
votes

Since Rollup 12 for CRM 2011 Metadata query is available. So instead of querying of all entities you can try to build query and get only one entity.