How do you handle the fetchxml result data?

Luke Baulch picture Luke Baulch · Jul 31, 2009 · Viewed 9.6k times · Source

I have avoided working with fetchxml as I have been unsure the best way to handle the result data after calling crmService.Fetch(fetchXml). In a couple of situations, I have used an XDocument with LINQ to retrieve the data from this data structure, such as:

XDocument resultset = XDocument.Parse(_service.Fetch(fetchXml));
if (resultset.Root == null || !resultset.Root.Elements("result").Any())
{
    return;
}
foreach (var displayItem in resultset.Root.Elements("result").Select(item => item.Element(displayAttributeName)).Distinct())
{
    if (displayItem!= null && displayItem.Value != null)
    {
        dropDownList.Items.Add(displayItem.Value);    
    }
}

What is the best way to handle fetchxml result data, so that it can be easily used. Applications such as passing these records into an ASP.NET datagrid would be quite useful.

Answer

Fishcake picture Fishcake · Aug 11, 2009

I enjoy the flexibility of FetchXML and so I developed the following function that returns a datatable for use in binding to grids and repeaters and so forth.

        /// <summary>
    /// Takes a CRM FetchXML query and returns a DataTable
    /// </summary>
    /// <param name="fetchXml">The FetchXML query</param>
    /// <param name="requiredFields">A array of columns you'd expect returned. This is required as if there is no data for a field/column CRM will not return it which could impact databinding</param>
    /// <returns>A datatable containing the results of the FetchXML</returns>
    public static DataTable FetchXML2DataTable(string fetchXml, string[] requiredFields)
    {
        CrmService tomService = new CrmService();
        tomService = CrmWebService;

        string result = tomService.Fetch(fetchXml);
        DataSet ds = new DataSet();

        System.IO.StringReader reader = new System.IO.StringReader(result);
        ds.ReadXml(reader);

        DataTable dt = ds.Tables[1];

        //check all required columns are present otherwise add them to make life easier for databinding at the top level
        //caused by CRM not returning fields if they contain no data
        foreach (string field in requiredFields)
        {   //Check for column names and nested tables
            if ((dt.Columns.IndexOf(field) < 0) && (dt.DataSet.Tables.IndexOf(field) <0))
            {                    
                //Add column to datatable even though it is empty for reason stated above
                dt.Columns.Add(new DataColumn(field));
            }
        }            

        return dt;
    }

The requiredFields string array is there because columns aren't returned if your result set contains no data with that column, however I might want the column in place for the exact reason of binding to datagrids etc.

CrmService is a singleton class that initates the webservice.

Hopefully this is of use to you.