Search code examples
c#linqdynamics-crmcrmdynamics-crm-4

How to create a non-nullable CRM basic type like int or double?


When we create a new field in Microsoft Dynamics CRM, it will create it in the database as NULL allowed. How can you create a field in CRM that is NON-NULL in the backing database, like they do use for some of their own fields?

Selecting the Mandatory flag doesn't make it NON-NULL.

Reason for asking: when programming against CRM using LINQ, many queries become relatively difficult when you have to take care of nullables, and some even become impossible, like aggregate queries (try Max(), it will give a InvalidCastException when the underlying db type is nullable).


Solution

  • Though not exactly what you're asking for, you can achieve a similar effect via the API. Write a plugin against the Create and Update in the pre-validation stage (to catch the null value before the database transaction). If the non-nullable attribute is ever null, throw an exception, which will cancel the transaction altogether.

    If you register the plugin after records have already been created, then you'd just have to make sure to populate those pre-existing records with values.

    public void Execute(IServiceProvider serviceProvider)
    {
        IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    
        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
        {
            var target = ((Entity)context.InputParameters["Target"]);
            if (target.LogicalName == Appointment.EntityLogicalName)
            {
                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                var entity = target.ToEntity<Xrm.Appointment>();
    
                if (entity.Description == null && entity.Attributes.Contains("description"))
                {
                    throw new Microsoft.Xrm.Sdk.SaveChangesException("Fill in the field, buddy.");
                }
            }
        }
    }