Warm tip: This article is reproduced from serverfault.com, please click

Dynamics CRM 2013 Workflow C# Extract Field from Linked Entity

发布于 2020-11-30 03:53:20

I'm trying to get a field from a related CRM Entity in a Dynamics CRM 2013 Workflow. The below code returns the mapped entity but it isn't referencing the matching record in the entity.

How can I update it so it runs the below query against two matched entity Guids? Do I need to use EntityReference?

   QueryExpression FindAddressLots = new QueryExpression(context.PrimaryEntityName);
                    FindAddressLots.LinkEntities.Add
                      (new LinkEntity(context.PrimaryEntityName, "appdetails_data", "applicationdetailsid", "appdetails_dataid", JoinOperator.Inner));
        
             FindAddressLots.LinkEntities[0].Columns.AddColumns("appdetails_dataid", "suburb", "postcode");
    FindAddressLots.LinkEntities[0].EntityAlias = "lotdata";
        
    EntityCollection ec = service.RetrieveMultiple(FindAddressLots);
        
                    foreach (Entity act in ec.Entities)
                    {
        
                      if (act.Attributes.Contains("lotdata.suburb"))
                        {
                          FindAddressLots = act.GetAttributeValue<AliasedValue>("lotdata.suburb").Value.ToString();
                         }
                    }
                }

Any suggestions? This would be much appreciated. Thanks.

Questioner
Michael
Viewed
0
Guido Preite 2020-12-02 18:20:28

Let's clarify one thing first: we don't know the type of field suburb, in my code I will assume it's a string but it can be something else.

Query code can be rewritten as the following (link properties, columns and alias are the same):

QueryExpression queryAddressLots = new QueryExpression(context.PrimaryEntityName);
LinkEntity linkDetails = queryAddressLots.AddLink("appdetails_data", "applicationdetailsid", "appdetails_dataid", JoinOperator.Inner);
linkDetails.Columns.AddColumns("appdetails_dataid", "suburb", "postcode");
linkDetails.EntityAlias = "lotdata";
EntityCollection collAddressLots = service.RetrieveMultiple(queryAddressLots);

According to the code there isn't a logic to retrieve a specific record (but usually there is) otherwise this will return all Address Lots joined with the details entity (I also wrote a comment before, nobody cares for the real entity names but they should be exact, when I read a field called applicationdetailsid people can assume there is an entity called applicationdetails and this entity does not exist)

Second part is how the value is fetched, that can be rewritten as (also here, variable names, something called act or ec should not be used):

foreach (Entity addressLot in collAddressLots.Entities)
{
    AliasedValue aliasSuburb = addressLot.GetAttributeValue<AliasedValue>("lotdata.suburb");
    if (aliasSuburb != null && aliasSuburb.Value != null)
    {
        string suburb = (string)aliasSuburb.Value;
    }
}

note that I did a cast to string, because as I wrote before I assumed the field is a string, if the field was a Whole Number I would probably do something like Convert.ToInt32(aliasSuburb.Value)

Now, the question mentions it isn't referencing the matching record in the entity, I assume it refers to the fact (as I wrote before) that no id was provided and all the records were returned. This can be easily solved by adding a condition just after the QueryExpression definition, something like:

queryAddressLots.Criteria.AddCondition("applicationdetailsid", ConditionOperator.Equal, context.PrimaryEntityId);

Of course we can't guarantee if this works, because we don't know the field names, hopefully the author knows. To be honest we can probably just query this appdetails_data entity and adding a condition to just match the applicationdetailsid (to me it looks like a N:1 relationship and not a 1:N relationship) and querying the suburb field without using a LinkEntity but I can't be 100% sure.

Hope it helps, and next time, please don't hide the entity and field names, just change the prefix.