Search code examples
c#dynamics-crmcrmfetchxml

Access second level linked entity from FetchXML


Here is the fetchXML:

<fetch version='1.0' mapping='logical' distinct='true'>
  <entity name='listmember'>
    <link-entity name='contact' from='contactid' to='entityid' alias='c'>
      <attribute name='contactid' />
      <attribute name='telephone1' />

      <link-entity name='phonecall' from='ic_customer' to='contactid' alias='pc' link-type='outer'>
        <attribute name='activityid' />
        <attribute name='ic_end' />
        <filter type='and'>
          <filter type='or'>
            <condition attribute='statuscode' operator='eq' value='1' />
          </filter>
        </filter>
      </link-entity>

      <filter type='and'>
        <condition attribute='statecode' operator='eq' value='0' />
        <condition attribute='telephone1' operator='not-null' />
        <condition attribute='donotphone' operator='eq' value='0' />
      </filter>
    </link-entity>
    <filter type='and'>
      <condition attribute='listid' operator='in'><value>{ed0fa81c-1b65-e611-80ee-5065f38be311}</value></condition>
      <condition entityname='pc' attribute='activityid' operator='null' />
    </filter>
  </entity>
</fetch>

Now I want to access the ic_end attribute when I got object through RetrieveMultiple method in C#.

I tried to get attribute via:

var endDate = (DateTime)((AliasedValue)contact["c.pc.ic_end"]).Value;

I got an error that no attribute with that name was found.

Any suggestions?


Solution

  • Few things here:

    First and foremost the way you retrieve the linked-entity attribute is incorrect, the attributes are returned in a format of alias.attributename (pc.ic_end in this case).

    Also always check if the attribute exists based on your join criteria it may not always be returned. Retrieve attribute logic should be along the lines of:

    if (contact.Attributes.Contains("pc.ic_end") && 
        contact.Attributes["pc.ic_end"] != null)
    {
        var endDate = (DateTime) ((AliasedValue) contact["pc.ic_end"]).Value;
    }
    

    link-entity name='phonecall' from='ic_customer' to='contactid' alias='pc' link-type='outer'

    I got an error that no attribute with that name was found.

    As soon as you have the link-type specified as outer, all contacts With OR Without phone call records are returned. So this is an intended behaviour, you would need to check if the attribute exists in the attribute list returned.

    If you want the query to only ever return a contact record With a phone call, use a natural inner join

    <link-entity name='phonecall' from='ic_customer' to='contactid' alias='pc'>