简体   繁体   中英

Dynamics Crm: Get metadata for statuscode/statecode mapping

In Dynamics CRM 2011, on the Incident entity, the "Status Reason" optionset (aka statuscode) is related to the "Status" optionset (aka statecode)

eg see this screenshot

CRM字段选项的屏幕截图

When I use the API to retrieve the Status Reason optionset, like so:

        RetrieveAttributeRequest attributeRequest = new RetrieveAttributeRequest
        {
            EntityLogicalName = "incident",
            LogicalName = "statuscode",
            RetrieveAsIfPublished = true
        };
        RetrieveAttributeResponse attributeResponse = (RetrieveAttributeResponse)serv.Execute(attributeRequest);
        AttributeMetadata attrMetadata = (AttributeMetadata)attributeResponse.AttributeMetadata;
        StatusAttributeMetadata statusMetadata = (StatusAttributeMetadata)attrMetadata;
        var dict = new Dictionary<int?, string>();
        foreach (OptionMetadata optionMeta in statusMetadata.OptionSet.Options)
        {
            dict.Add(optionMeta.Value, optionMeta.Label.UserLocalizedLabel.Label);
        }

It works in that I get the whole list of "Status Reason" (statuscode) options. However, I dont get any info about which "Status Reason" (statuscode) options relate to which "Status" (statecode) options.

How do I get that information?

You already have everything try insert this code inside of foreach:

 int stateOptionValue = (int)((StatusOptionMetadata)optionMeta).State;

See StatusAttributeMetaData.OptionSet.Options hierarchy can return a type called StatusOptionMetadata if you use the State property of the StatusOptionMetadata, it will return the statecode this statuscode belongs to.

Here is how you can get it by querying the database

SELECT distinct e.LogicalName as entity,
      smState.Value AS stateCode,
      smstate.AttributeValue,
      smStatus.Value AS [statuscode/statusreason],
      smStatus.AttributeValue
FROM StatusMap sm
     JOIN Entity e ON sm.ObjectTypeCode = e.ObjectTypeCode
     JOIN StringMap smState ON smState.AttributeValue = sm.State
                           AND smState.ObjectTypeCode = e.ObjectTypeCode
                           AND smState.AttributeName = 'StateCode'
     JOIN StringMap smStatus ON smStatus.AttributeValue = sm.Status
                            AND smStatus.ObjectTypeCode = e.ObjectTypeCode
                            AND smStatus.AttributeName = 'StatusCode'
WHERE  e.LogicalName in ('lead')
ORDER BY e.LogicalName,
      smState.AttributeValue,
      smStatus.AttributeValue;

Here is working code that will output State/Status mapping for a given entity (you just need to provide the orgServiceProxy):

    var dictState = new Dictionary<int, OptionMetadata>();
    var dictStatus = new Dictionary<int, List<OptionMetadata>>();

    string entityName = "lead";
    int count=0;
    using (var orgServiceProxy = GetOrgServiceProxy(orgServiceUriOnLine))
    {
        RetrieveAttributeResponse attributeResponse = GetAttributeData(orgServiceProxy, entityName, "statecode");
        AttributeMetadata attrMetadata = (AttributeMetadata)attributeResponse.AttributeMetadata;
        StateAttributeMetadata stateMetadata = (StateAttributeMetadata)attrMetadata;
        foreach (OptionMetadata optionMeta in stateMetadata.OptionSet.Options)
        {
            dictState.Add(optionMeta.Value.Value,optionMeta);
            dictStatus.Add(optionMeta.Value.Value,new List<OptionMetadata>());
        }

        attributeResponse = GetAttributeData(orgServiceProxy, entityName, "statuscode");
        attrMetadata = (AttributeMetadata)attributeResponse.AttributeMetadata;
        StatusAttributeMetadata statusMetadata = (StatusAttributeMetadata)attrMetadata;

        foreach (OptionMetadata optionMeta in statusMetadata.OptionSet.Options)
        {
            int stateOptionValue = ((StatusOptionMetadata)optionMeta).State.Value;
            var statusList = dictStatus[stateOptionValue];
            statusList.Add(optionMeta);
            count++;
        }
    }
    Console.WriteLine($"Number of mappings: {count}");
    foreach (var stateKvp in dictState.OrderBy(x=> x.Key))
    {
        Console.WriteLine($"State: {stateKvp.Value.Value}: {stateKvp.Value.Label.UserLocalizedLabel.Label}");
        var statusList = dictStatus[stateKvp.Key];
        Console.WriteLine($"\tStatuses");
        foreach (var status in statusList.OrderBy(s => s.Value))
        {
            Console.WriteLine($"\t\t{stateKvp.Value.Value}: {status.Label.UserLocalizedLabel.Label}");
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM