web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :

Simple C# class to populate datatable from FetchXML

lucasalexander Profile Picture lucasalexander 886

I've typically preferred to access Dynamics CRM data using SQL queries, so I have never worked much with FetchXML. I've recently started working on a bit of a hobby project where it makes more sense to populate a datatable from using FetchXML than to use a SQL query, but unfortunately I have encountered three differences between FetchXML and direct SQL that I don't particularly like:

  1. FetchXML results do not include attributes that are not populated in CRM, even if they are explicitly requested in the query.
  2. You can't retrieve the label for a picklist using the attribute name + "name" convention.
  3. Your code has to add additional logic to deal with AliasedValues, EntityReferences, etc.
Here is a class I wrote to execute a FetchXML query and populate a datatable with the results.
class QueryUtility
{
	public DataTable ExecuteFetchXml(string fetchXmlFragment, IOrganizationService service)
	{
		//execute fetchxml
		FetchExpression fetch = new FetchExpression(fetchXmlFragment);
		EntityCollection fetchresults = service.RetrieveMultiple(fetch);
		
		DataTable resultsTable = new DataTable("results");
		if (fetchresults.Entities.Count > 0)
		{
			for(int i=0;i<fetchresults.Entities.Count;i++)
			{
				var entity = fetchresults.Entities[i];
				DataRow row = resultsTable.NewRow();
				foreach (var attribute in entity.Attributes)
				{
					if (!resultsTable.Columns.Contains(attribute.Key))
					{
						resultsTable.Columns.Add(attribute.Key);
					}
					row[attribute.Key] = getAttributeValue(attribute.Value).ToString();
				}
				foreach (var fv in entity.FormattedValues)
				{
					if (!resultsTable.Columns.Contains(fv.Key + "name"))
					{
						resultsTable.Columns.Add(fv.Key + "name");
					}
					row[fv.Key + "name"] = fv.Value;
				}

				resultsTable.Rows.Add(row);
			}
		}
		return resultsTable;
	}

	private object getAttributeValue(object entityValue)
	{
		object output = "";
		switch (entityValue.ToString())
					{
						case "Microsoft.Xrm.Sdk.EntityReference":
							output = ((EntityReference)entityValue).Name;
							break;
						case "Microsoft.Xrm.Sdk.OptionSetValue":
							output = ((OptionSetValue)entityValue).Value.ToString();
							break;
						case "Microsoft.Xrm.Sdk.Money":
							output = ((Money)entityValue).Value.ToString();
							break;
						case "Microsoft.Xrm.Sdk.AliasedValue":
							output = getAttributeValue(((Microsoft.Xrm.Sdk.AliasedValue)entityValue).Value);
							break;
						default:
							output = entityValue.ToString();
							break;
					}
		return output;
	}
}

This was originally posted here.

Comments

*This post is locked for comments