Retrieve Marketinglists attached to Campaign Activity

Today I've been doing some coding again and I've found an interesting situation. For my code I do need to find which marketing lists belong to a specific Campaign Activity. Apparently more people on the internet faced the same issue, but I haven't found anybody who supplied the answer on how to do that.

I've managed to find an approach which works for both the fetchXml as well as a QueryExpression. Here is the code for both of these options:

FetchXml:


StringBuilder sbFetchXml = new StringBuilder();
sbFetchXml.Append("<fetch version=\"1.0\" output-format=\"xml-platform\" mapping=\"logical\" distinct=\"true\">");
sbFetchXml.Append("<entity name=\"list\">");
sbFetchXml.Append("<attribute name=\"listname\"/><attribute name=\"listid\"/>");
sbFetchXml.Append("<order attribute=\"listname\" descending=\"true\"/>");
sbFetchXml.Append("<link-entity name=\"campaignactivityitem\" from=\"itemid\" to=\"listid\" visible=\"false\" intersect=\"true\">");
sbFetchXml.Append("<link-entity name=\"campaignactivity\" from=\"activityid\" to=\"campaignactivityid\" alias=\"aa\">");
sbFetchXml.Append("<filter type=\"and\">");
sbFetchXml.AppendFormat("<condition attribute=\"activityid\" operator=\"eq\" uitype=\"campaignactivity\" value=\"{0}\"/>", campaignActivityId);
sbFetchXml.Append("</filter>");
sbFetchXml.Append("</link-entity>");
sbFetchXml.Append("</link-entity>");
sbFetchXml.Append("</entity>");
sbFetchXml.Append("</fetch>");

string strXmlResult = service.Fetch(sbFetchXml.ToString());


QueryExpression:

ConditionExpression condActivityId = new ConditionExpression();
condActivityId.AttributeName = "activityid";
condActivityId.Operator = ConditionOperator.Equal;
condActivityId.Values = new object[] { campaignActivityId };

FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.And;
filter.Conditions = new ConditionExpression[] { condActivityId };

LinkEntity leCampaignActivity= new LinkEntity();
leCampaignActivity.LinkFromEntityName = EntityName.campaignactivityitem.ToString();
leCampaignActivity.LinkFromAttributeName = "campaignactivityid";
leCampaignActivity.LinkToEntityName = EntityName.campaignactivity.ToString();
leCampaignActivity.LinkToAttributeName = "activityid";
leCampaignActivity.LinkCriteria = filter;

LinkEntity leCampaignActivityItem = new LinkEntity();
leCampaignActivityItem.LinkFromEntityName = EntityName.list.ToString();
leCampaignActivityItem.LinkFromAttributeName = "listid";
leCampaignActivityItem.LinkToEntityName = EntityName.campaignactivityitem.ToString();
leCampaignActivityItem.LinkToAttributeName = "itemid";
leCampaignActivityItem.LinkEntities = new LinkEntity[] {leCampaignActivity};

QueryExpression query = new QueryExpression();
query.EntityName = EntityName.list.ToString();
query.ColumnSet = new AllColumns();
query.LinkEntities = new LinkEntity[] { leCampaignActivityItem };

BusinessEntityCollection bec = service.RetrieveMultiple(query);

For me this worked, I hope this helps you as well!

2 comments:

Zato said...

This is very helpful. Thanks!

roco said...

Hello! I used this with the 4.0 endpoint, but with the 2011 endpoint I get an exception. Any ideas?

ConditionExpression condActivityId = new ConditionExpression();
condActivityId.AttributeName = "activityid";
condActivityId.Operator = ConditionOperator.Equal;
condActivityId.Values.Add(new object[] { campaignActivityId });

FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.And;
filter.Conditions.Add(condActivityId);

LinkEntity leCampaignActivity = new LinkEntity();
leCampaignActivity.LinkFromEntityName = CampaignActivityItem.EntityLogicalName;
leCampaignActivity.LinkFromAttributeName = "campaignactivityid";
leCampaignActivity.LinkToEntityName = CampaignActivity.EntityLogicalName;
leCampaignActivity.LinkToAttributeName = "activityid";
leCampaignActivity.LinkCriteria = filter;

LinkEntity leCampaignActivityItem = new LinkEntity();
leCampaignActivityItem.LinkFromEntityName = List.EntityLogicalName;
leCampaignActivityItem.LinkFromAttributeName = "listid";
leCampaignActivityItem.LinkToEntityName = CampaignActivityItem.EntityLogicalName;
leCampaignActivityItem.LinkToAttributeName = "itemid";
leCampaignActivityItem.LinkEntities.Add(leCampaignActivity);

QueryExpression qeListsOnCampaignActivity = new QueryExpression();
qeListsOnCampaignActivity.EntityName = List.EntityLogicalName;
qeListsOnCampaignActivity.ColumnSet = new ColumnSet(true);
qeListsOnCampaignActivity.LinkEntities.Add(leCampaignActivityItem);

// Create the request object.
// Set the properties of the request object.
var retrieve = new RetrieveMultipleRequest { Query = qeListsOnCampaignActivity };

// Execute the request.
var retrieved = (RetrieveMultipleResponse)_crmHelper.OrganizationService.Execute(retrieve);



The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://schemas.microsoft.com/xrm/2011/Contracts/Services:request. The InnerException message was 'Error in line 1 position 1733. Element 'http://schemas.microsoft.com/2003/10/Serialization/Arrays:anyType' contains data from a type that maps to the name 'http://schemas.microsoft.com/2003/10/Serialization/Arrays:ArrayOfanyType'. The deserializer has no knowledge of any type that maps to this name. Consider changing the implementation of the ResolveName method on your DataContractResolver to return a non-null value for name 'ArrayOfanyType' and namespace 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'.'. Please see InnerException for more details.