Skip to content

FluentCRM entity subclass

rogerhillgsy edited this page Mar 29, 2019 · 1 revision

#Fluent CRM Entity subclass

This can most conveniently be created using the FLuentCRMTemplate code snippet.

Some further points are noted below the text.

using System;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk;

namespace FluentCRM
{
    /// <summary>
    /// FluentCRM class used to encapsulate access to the Account Entity
    /// </summary>
    public class FluentAccount : FluentCRM
    {

        private const string _logicalName = "account";

        #region "Constructors etc required by Language"
        private FluentAccount(Guid id, IOrganizationService service) : base(_logicalName, id, service) { }

        private FluentAccount(IOrganizationService service) : base(_logicalName, service) { }

        private FluentAccount(Guid id) : base(_logicalName, id) { }

        /// <summary>
        /// Select specific entity with given id value using specified IOrganizationService
        /// </summary>
        /// <param name="id">Guid of entity to select</param>
        /// <param name="service">CRM system to fetch entity from</param>
        /// <returns>FluentCRM subclass - returns even if ID does not exist.</returns>
        public static IEntitySet Account(Guid id, IOrganizationService service)
        {
            return new FluentAccount(id, service);
        }

        /// <summary>
        /// Select a (sub)set of the specified entity using specified IOrganizationService
        /// </summary>
        /// <param name="service">CRM system to fetch entity from</param>
        /// <returns>FluentCRM subclass that can be used to filter and operate on the specified entity type.</returns>
        public static IUnknownEntity Account(IOrganizationService service)
        {
            return new FluentAccount(service);
        }

        /// <summary>
        /// Select specific entity with given id value using the static organization service specified by FluentCRM.StaticService
        /// </summary>
        /// <param name="id">Guid of entity to operator on</param>
        /// <returns>FluentCRM subclass - returns even if ID does not exist.</returns>
        public static IEntitySet Account(Guid id)
        {
            return new FluentAccount(id);
        }

        /// <summary>
        /// Select a (sub)set of the specified entity using the static organization service specified by FluentCRM.StaticService
        /// </summary>
        /// <returns>FluentCRM subclass that can be used to filter and operate on the specified entity type.</returns>
        public static IUnknownEntity Account()
        {
            return new FluentAccount();
        }

        /// <summary>
        /// Parameterless constructor required by the language, but not necessarily used.
        /// </summary>
        public FluentAccount() : base(_logicalName) { }

        /// <summary>
        /// Factory method to return an instance of the FluentCRM entity class with the given CRM connection.
        /// </summary>
        /// <param name="service">CRM system to fetch entity from</param>
        /// <returns>FluentCRM subclass that can be used to filter and operate on the specified entity type.</returns>
        public override IJoinable Factory(IOrganizationService service)
        {
            return new FluentAccount(service);
        }
        #endregion

        /// <summary>
        /// Use to specify where join parameters to other entites are non-standard.
        /// </summary>
        private readonly Dictionary<string, string> _joinOn = new Dictionary<string, string>
        {
            // if the join to another entity is through the primary id field, (1:N join) nothing is needed here.
            // If it is through another field (N:1 join) then the details of the foreign entity and lookup field need to be given here.
            //
            // { "foreign entity logical name", "logical name of lookup field in this entity" }
            //   { "account", "parentcustomerid" } 
        };

        /// <summary>
        /// Internal-use function used to get the name of the "this entity" attribute to be used to join to the specified "foreign" entity .
        /// </summary>
        /// <param name="foreignEntityName"></param>
        /// <returns>Name of "this entity" attribute to be used to join to the given "foreign" entity.</returns>
        public override string JoinAttribute(string foreignEntityName)
        {
            if (_joinOn.ContainsKey(foreignEntityName))
            {
                return _joinOn[foreignEntityName];
            }
            else
            {
                return "accountid";
            }
        }
    }
}
  1. Each Fluent CRM subclass represents a CRM entitiy.
    This can be a built-in entity, or a custom, user defined, entity.
  2. Bear in mind that much of the code in the FluentCRM subclass is required by the language syntax (constructors, Factory functions).
    If the code snippet template is used to generate the subclass, this will deal with the correct completion of the code, in particular ensuring that it is consistent in naming the various constructors and factory methods.
  3. The _joinOn dictionary and or/JoinAttribute functions only need customization where there are specific join requirements. See Joins
  4. In some cases it may make sense to add additional code to the FluentCRM subclass. For example FluentSystemUser includes a method "CurrentUser" which selects the record for the calling user.
  5. The FluentCRM subclasses can be further subclassed, for example to provide specific join behaviour - see FluentPrimaryContact.
  6. The most important requirement is that the logical name for the underlying CRM entity is set correctly.
  7. The actual name of the FLuentCRM subclass can be anything you want (and doesn't have to start with Fluent... either).
    The only important thing is that it is a subclass of FluentCRM.
Clone this wiki locally