Вопрос

I'm fetching Contactand Account entities and I wish to access the name of the contact and the name of the primary contact. While the first one is accessed very easily by

EntityCollection result = proxy.RetrieveMultiple(...);
Entity entity = result.Entities[0].Attributes["fullname"];

the other seems to fight me throwing an exception. As far I can see, it depends on the fetch XML that has attributes for the name directly in <entity> in the former case and under <entity><link-entity> in the latter.

How can I access the field fullname that is a linked entity?


Fetch XML for contacts:

<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
  <entity name='contact'>
    <attribute name='fullname' />
  </entity>
</fetch>

Fetch XML for accounts' primary contacts:

<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
  <entity name='account'>
    <attribute name='accountid'/>
    <link-entity name='listmember' from='entityid' to='accountid' visible='false' intersect='true'>
      <link-entity name='list' from='listid' to='listid' alias='ab'>
      </link-entity>
    </link-entity>
    <link-entity name='contact' from='contactid' to='primarycontactid' visible='false' link-type='outer' alias='...'>
      <attribute name='fullname'/>
    </link-entity>
  </entity>
</fetch>
Это было полезно?

Решение

This is a response to the original question, the answer from GCTANM and comments (my thoughts are too long for the comments).

There appears to be a couple of confusions here I would like to clear up.

GCTANM:

RetrieveMultiple can only use LinkEntities for selection purposes, it cannot return attributes for entities other than the primary entity of the query.

...

for any other attributes of those contact records, you'd have to take each contact's ID and do one of those Retrieve calls mentioned in my comment.

These statements are not correct, you can return attributes of all the linked entities as well. There is an example of this on the MSDN.

Chamster

By the sound of its name, Fetch will only return a single result, won't it?

FetchXml returns a single result set, but that result set can contain the details of many records.

Somehow, I'd prefer to work with XML than entities

If you really (really really) wanted to do that you could use the Crm 4 Web Services, the RetrieveMultiple still returns an Xml result set.

To answer the original question.

So the reason your probably struggling to get back your attribute it because the EntityCollection that is returned has a slightly peculiar behaviour which was introduced in Crm 2011.

In short, Crm 4 FetchXml queries would return an Xml result you had to parse, in 2011 to help you out Microsoft parse the result into an EntityCollection. This results in some attributes having quite unexpected names.

So taking the example of you contact above, you would have to access the fullname attribute using something like this: contact1.fullname, the contact is the link, the number is representative of the number of links, and fullname is the attribute.

I can't remember the exact format and I'm struggling to find a decent example. I would suggest setting a breakpoint after your query and inspecting the results, I'm certain you will find the data but with names like above.

If I can find a decent example (or create one tommorrow) I'll update my post.

Другие советы

RetrieveMultiple can only use LinkEntities for selection purposes, it cannot return attributes for entities other than the primary entity of the query.

However, when you include the primarycontactid attribute in the ColumnSet for the account query, that will be an EntityReference whose Name property contains the fullname of the contact. That's coincidental though, as the fullname attribute is the "primary name" attribute of the contact entity, and that's what's used in EntityReference objects.

Elaborating, as you requested:

RetrieveMultiple takes a QueryBase object (most commonly a QueryExpression), which has a property called ColumnSet to define which attributes to return (which can make a difference in performance, especially for entities with many fields).

In your case, it might be set up like this:

QueryExpression qryAccounts = new QueryExpression("account")
{
    ColumnSet = new ColumnSet("accountid", "name", "primarycontactid")
};

qryAccounts.Criteria.AddCondition("primarycontactid", ConditionOperator.NotNull);

qryAccounts.AddLink("list", "accountid", "entityid");


EntityCollection collAccounts = svcOrganization.RetrieveMultiple(qryAccounts);

Now, if any of the records returned in collAccounts.Entities has a primary contact (in this case, they all will, because that was one of our conditions, aka select clauses), its Attributes collection will include an item keyed primarycontactid, and the value will be of type EntityReference.

This has the properties Id, LogicalName (this being the name of the referenced entity, in this case "contact") and Name, which is the value of the entity's primary name attribute; for contact, that is fullname (for account it's name, and so on - always the name that you see in grids or lookups for the respective entity).

But as I said, that is a coincidence, and for any other attributes of those contact records, you'd have to take each contact's ID and do one of those Retrieve calls mentioned in my comment.

A Fetch using actual FetchXML (with the result also being XML) can directly return attributes of linked records, as far as I remember.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top