Crm Sdk: Extension Methods for the CrmService

I often find it tedious writing something like the following:

//Instantiate our ColumnSet with desired columns.
ColumnSet cols = new ColumnSet() { Attributes = new string[] { "firstname", "lastname" } };
//Call the Retrieve method on crmService for our desired contact
contact c = (contact)_crmService.Retrieve(EntityName.contact.ToString(), new Guid("7C0F232E-7F72-DE11-8397-0015C5E3FA2"), cols);

Although we know the type we are fetching, in this case ‘contact’, we still have to make an explicit cast from a BusinessEntity. This is where generics can help. Another thing I find annoying is the type name is always the same, yet again I end up providing it. Here is my proposed solution:

//Using a custom extension method we now have a nice single line approach and no casting needs to be done.
contact c = _crmService.Retrieve<contact>(new Guid("7C0F232E-7F72-DE11-8397-0015C5E3FA2"), new string[] { "firstname", "lastname" });

Here I have created a generic extension method that accepts a BusinessEntity Type and simply uses the name of that type in the Retrieve. It also performs our explicit cast for us! =) I really do love the power of extension methods.

public static TEntity Retrieve<TEntity>(this CrmService _service, Guid entityId, string[] columns) where TEntity : BusinessEntity, new() {
return (TEntity)_service.Retrieve(typeof(TEntity).Name, entityId, new ColumnSet() { Attributes = columns });
}

Of course you can provide some extra functionality, for example a TryRetrieve method that catches the raised exception that notifies you that the entity does not exist.

Here is some more examples:

namespace CrmHelpers
{
    /// <summary>
    /// A few examples of extension methods, specifically for the CrmSdk.
    /// </summary>
    public static class CrmHelpers
    {
        /// <summary>
        /// Retrieves a BusinessEntity from the CrmService.
        /// </summary>
        /// <typeparam name="TEntity">The entity type</typeparam>
        /// <param name="_service"></param>
        /// <param name="entityId">The Guid of the entity you wish to receive</param>
        /// <returns>A BusinessEntity</returns>
        public static TEntity Retrieve<TEntity>(this CrmService _service, Guid entityId) where TEntity : BusinessEntity, new()
        {
            return (TEntity)_service.Retrieve(typeof(TEntity).Name, entityId, new AllColumns());
        }

        /// <summary>
        /// Retrieves a BusinessEntity from the CrmService.
        /// </summary>
        /// <typeparam name="TEntity">The entity type</typeparam>
        /// <param name="_service"></param>
        /// <param name="entityId">The Guid of the entity you wish to receive</param>
        /// <param name="columns">A string array of columns to retrieve</param>
        /// <returns>A BusinessEntity</returns>
        public static TEntity Retrieve<TEntity>(this CrmService _service, Guid entityId, string[] columns) where TEntity : BusinessEntity, new()
        {
            return (TEntity)_service.Retrieve(typeof(TEntity).Name, entityId, new ColumnSet() { Attributes = columns });
        }

        /// <summary>
        /// Tries to retrieve a BusinessEntity from the CrmService, if not found it will return null.
        /// </summary>
        /// <typeparam name="TEntity">The entity type</typeparam>
        /// <param name="_service"></param>
        /// <param name="entityId">The Guid of the entity you wish to receive</param>
        /// <returns>A BusinessEntity</returns>
        public static TEntity TryRetrieve<TEntity>(this CrmService _service, Guid entityId) where TEntity : BusinessEntity, new()
        {
            string entityName = typeof(TEntity).Name;
            try
            {
                TEntity entity = (TEntity)_service.Retrieve(entityName, entityId, new AllColumns());
                return entity;
            }
            catch (SoapException sex)
            {
                XmlNode n = sex.Detail.SelectSingleNode("//error//code");
                if (n.InnerText == "0x80040217")
                    return null;
                else throw new ApplicationException(sex.Detail.InnerText, sex);
            }
        }

        /// <summary>
        /// Not a practical method. Just an example.
        /// </summary>
        /// <typeparam name="TEntity">The entity type</typeparam>
        /// <param name="_service"></param>
        /// <returns>An IEnumerable collection of BusinessEntity objects</returns>
        public static IEnumerable<TEntity> RetrieveAllActive<TEntity>(this CrmService _service) where TEntity : BusinessEntity, new()
        {
            try
            {
                QueryExpression qe = new QueryExpression()
                {
                    ColumnSet = new AllColumns(),
                    EntityName = typeof(TEntity).Name,
                    Criteria = new FilterExpression()
                    {
                        Conditions = new ConditionExpression[] {
                         new ConditionExpression(){ AttributeName = "statecode",
                             Operator = ConditionOperator.Equal,
                             Values = new object[] { 0 } }
                     },
                        FilterOperator = LogicalOperator.And
                    }
                };

                return _service.RetrieveMultiple(qe).BusinessEntities.Cast<TEntity>();
            }
            catch (SoapException sex)
            {
                throw new ApplicationException(sex.Detail.InnerText, sex);
            }
        }

        /// <summary>
        /// Creates and Retrieves a BusinessEntity
        /// </summary>
        /// <typeparam name="TEntity">The type of BusinessEntity</typeparam>
        /// <param name="_service"></param>
        /// <param name="entity">The entity</param>
        /// <returns>The Entity created</returns>
        public static TEntity CreateAndRetrieve<TEntity>(this CrmService _service, TEntity entity) where TEntity : BusinessEntity, new()
        {
            return (TEntity)_service.Retrieve(typeof(TEntity).Name, _service.Create(entity), new AllColumns());
        }

        public static DynamicEntity RetrieveDynamic(this CrmService _service, string entityName, Guid entityId)
        {
            RetrieveRequest req = new RetrieveRequest()
            {
                ColumnSet = new AllColumns(),
                ReturnDynamicEntities = true,
                Target = new TargetRetrieveDynamic()
                {
                    EntityId = entityId,
                    EntityName = entityName
                }
            };

            return (DynamicEntity)((RetrieveResponse)_service.Execute(req)).BusinessEntity;
        }

        public static DynamicEntity RetrieveDynamic(this CrmService _service, string entityName, Guid entityId, string[] columns)
        {
            RetrieveRequest req = new RetrieveRequest()
            {
                ColumnSet = new ColumnSet() { Attributes = columns },
                ReturnDynamicEntities = true,
                Target = new TargetRetrieveDynamic()
                {
                    EntityId = entityId,
                    EntityName = entityName
                }
            };

            return (DynamicEntity)((RetrieveResponse)_service.Execute(req)).BusinessEntity;
        }
    }
}

Tags: , ,

Leave a Comment