GetAttributeValue<T> is a method of the
Entity class, it is used to retrieve easily the entity's values. You can find a detailed overview by Dave Berry here:
Entity.GetAttributeValue Explained
Dynamics CRM includes a special data type called
ActivityParty (an overview
here) and despite its special status we can still use
GetAttributeValue<T> method against the fields using this data type.
First of all the
ActivityParty attributes hold an
EntityCollection of
activityparty entities, these entities are a pointer to the real records through the
partyid attribute (
EntityReference).
Entity email = service.Retrieve("email", emailId, new ColumnSet(true));
EntityCollection to = email.GetAttributeValue<EntityCollection>("to");
A big difference when using the
GetAttributeValue<T> with the
EntityCollection than the
EntityReference is the case when the attribute is
null.
With
EntityReference the method
GetAttributeValue<T> returns a
null if the attribute is empty.
EntityReference parentAccountRef = account.GetAttributeValue<EntityReference>("parentaccountid");
if (parentAccountRef != null) { /* code here */ }
With
EntityCollection we can have
null if the attribute is not inside the collection or an
EntityCollection with no values inside the
Entities property if the attribute is empty but inside the attributes list.
The second scenario is very common, for example when retrieving an email, the attributes
from,
to,
cc,
bcc are always returned.
Entity email = service.Retrieve("email", emailId, new ColumnSet(true));
EntityCollection to = email.GetAttributeValue<EntityCollection>("to");
EntityCollection cc = email.GetAttributeValue<EntityCollection>("cc");
if (to != null) { Console.WriteLine("Records inside To: " + to.Entities.Count.ToString(); }
if (cc != null) { Console.WriteLine("Records inside Cc: " + cc.Entities.Count.ToString(); }
Even if we have an usable
EntityCollection, it's necessary additional code to get the reference to the real records contained inside the
ActivityParty attributes.
To simplify the access to the values I created an extension method (called
GetEntityReferenceCollectionValue) to return an
EntityReferenceCollection from an
ActivityParty field:
public static EntityReferenceCollection GetEntityReferenceCollectionValue(
this Entity entity, string attributeLogicalName)
{
EntityReferenceCollection entityReferenceCollection = new EntityReferenceCollection();
EntityCollection entityCollection = entity.GetAttributeValue<EntityCollection>(attributeLogicalName);
if (entityCollection != null)
{
foreach (Entity item in entityCollection.Entities)
{
EntityReference partyIdReference = item.GetAttributeValue<EntityReference>("partyid");
if (partyIdReference != null) { entityReferenceCollection.Add(partyIdReference); }
}
}
return entityReferenceCollection;
}
EntityReferenceCollection is a class that holds a list of
EntityReference, it's normally used inside the Associate/Disassociate operations, but nothing stop us to reuse it to hold all the
EntityReference entries of an
EntityCollection.
The use is straightforward:
Entity email = service.Retrieve("email", emailId, new ColumnSet(true));
EntityReferenceCollection to = email.GetEntityReferenceCollectionValue("to");
If it's necessary to retrieve the actual entities I created a method called
GetEntitiesFromEntityReferenceCollection, it requires as parameters the
IOrganizationService and the
EntityReferenceCollection. The value returned is an
IEnumerable<Entity>:
public static IEnumerable<Entity> GetEntitiesFromEntityReferenceCollection(
IOrganizationService service, EntityReferenceCollection entityReferenceCollection)
{
List<Entity> entities = new List<Entity>();
foreach (EntityReference entityReference in entityReferenceCollection)
{
try
{
Entity entity = service.Retrieve(entityReference.LogicalName, entityReference.Id, new ColumnSet(true));
entities.Add(entity);
}
catch { }
}
return entities.AsEnumerable<Entity>();
}
Example:
Entity email = service.Retrieve("email", emailId, new ColumnSet(true));
EntityReferenceCollection to = email.GetEntityReferenceCollectionValue("to");
var toEntities = GetEntitiesFromEntityReferenceCollection(service, to);