Wednesday, November 30, 2011

Retrieving data using OData Service in CRM 2011


Everyone that uses CRM 2011 must have come across Odata service and might have used the Odata service for CRID operations. This works very well. However there is a small thing that we ought to be keeping in our mind when we are retrieving data using Odata service. That is it only returns the first 50 records. If you want to work with more than that then you have to change your Odata query.

There is a keyword that can be used. That is “top”. There is a good article and samples given in the CRM SDK. We have changed this to accommodate our needs.

We wanted to retrieve price list items whose start date is greater than a particular date and keep that in generic list. The code which was written has been pasted below.



private void SearchPriceLevel()
        {
            DataServiceQuery<PriceLevel> query = (DataServiceQuery<PriceLevel>)context.PriceLevelSet.AddQueryOption("$top", 100).
                Where(c => c.BeginDate <= Convert.ToDateTime("12/12/2011"));

            query.BeginExecute(ProcessPages<PriceLevel>, new PagingContext<PriceLevel>()
            {
                ServiceContext = _context,
                Query = query,
                PageProcessor = delegate(DataServiceCollection<PriceLevel> results)
                {
                    try
                    {

                        if (null == PriceLevelCollection)
                        {
                            PriceLevelCollection = new DataServiceCollection<PriceLevel>(_context);
                            PriceLevelCollection.Load(results);
                        }
                        else
                        {
                            for (int i = 0; i < results.Count; i++)
                            {
                                PriceLevelCollection.Add(results[i]);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                    }
                    return true;
                }
            });

        }
 

        private  void ProcessPages(IAsyncResult result)
        {
            try
            {
                PagingContext context = (PagingContext)result.AsyncState;

                QueryOperationResponse response;
                if (null == context.Query)
                {
                    response = (QueryOperationResponse)context.ServiceContext.EndExecute(result);
                }
                else
                {
                    response = (QueryOperationResponse)context.Query.EndExecute(result);
                    context.Query = null;
                }

                DataServiceCollection results = new DataServiceCollection(response);


                if (results != null && results.Count > 0)
                {
                    Type typeParameterType = typeof(T);
                    if (typeParameterType.Name.ToLower() == "pricelevel")
                    {
                        IEnumerable<PriceLevel> priceLevelItems = results.Cast<PriceLevel>();
                        OnSearchPriceLevelCompleted(priceLevelItems);
                    }
                }


                if (null != context.PageProcessor && !context.PageProcessor(results))
                {
                    return;
                }

                DataServiceQueryContinuation token = results.Continuation;
                if (null == token)
                {
                    priceLevelViewModel.PriceLevels = priceLevelCollection;

                    if (priceLevelViewModel.PriceLevels != null && priceLevelViewModel.PriceLevels.Count > 0)
                    {
                        SearchProductPriceLevel();
                    }
                    return;
                }

                context.ServiceContext.BeginExecute(token, ProcessPages, context);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void OnSearchPriceLevelCompleted(IEnumerable<PriceLevel> pl)
        {
            try
            {
                IEnumerator enumer = ((IEnumerable)pl).GetEnumerator();
                while (enumer.MoveNext())
                {
//This is a Generic list which contains Pricelevel items and it’s declared as a class variable
                    priceLevelCollection.Add((PriceLevel)enumer.Current);
                }
            }
            catch (Exception se)
            {
                

            }
        }



sealed class PagingContext
    {
        public DataServiceContext ServiceContext { get; set; }

        public DataServiceQuery Query { get; set; }

        public Func<DataServiceCollection, bool> PageProcessor { get; set; }
    }



You can find the code given for this from Microsoft at the following location of the CRM 2011 SDK.

sdk\samplecode\cs\silverlight\restendpointpagingsilverlight

You can find more information about this from the following links.



No comments:

Post a Comment

Retrieving Calendar of a Bookable Resource in Dynamics

There are occasions where we need to retrieve working days and working times of a resource in Dynamics grammatically. This is quite possible...