Access CRM Fields in an Efficient Way

31 March 2017
Daniel Cai

As a professional Dynamics 365/CRM developer, you want your code to be as efficient as possible. In your CRM project, you might often run into a code structure like something below.

if (entity.Attributes.Contains("myorg_myfield"))
{
    var fieldValue = entity.Attributes["myorg_myfield"];
    // Handle it based on there is a value with the field.
}
else
{
    // Handle it based on there is no value with the field.
}

You can find this particular code pattern almost everywhere, even including the sample code that is shipped with Dynamics 365/CRM SDK. However, there is a problem with this code structure, it is simply not as efficient as it can be!

Let me explain to you why.

CRM entity's Attributes property is essentially a property bag which contains all field values using an internal .NET dictionary. The dictionary uses field name as the key. What the above code does is, it first performs a lookup to check if the entity record contains a value for the field called myorg_myfield. When it determines that there is a value with the concerned field, it will try to perform another lookup of the dictionary to actually get the value for the field. The problem is, the code structure is essentially doing two lookup operations against the same internal dictionary. This should not be the way that you access information in a .NET dictionary, as there is a better way to do it!

Let's have a close look of the option available. .NET dictionary object has a TryGetValue method, which can be used to get value from the dictionary using a key. If it finds the key in the dictionary, the method returns a value of true, at the same time it return the value for the key in its only "out" parameter. If doesn't find one, the method's return value will be false indicating no such key exists in the dictionary, and the "out" parameter variable will have a null value. Using the TryGetValue method, your code would be something like the following.

object fieldValue;
if (entity.Attributes.TryGetValue("myorg_myfield", out fieldValue))
{
    // Handle it based on there is a value with the field.
}
else
{
    // Handle it based on there is no value with the field.
}

Using the new code structure, we are now only performing one lookup, and we know whether the CRM entity property bag contains a value for a particular field, and we also have the value with one single method call. Doing so, you have a performance improvement of 100% (in theory though), your code runs two times faster.

This may not be such a big issue if you are only accessing just one or even a few fields. But if your code runs within a loop structure or if you try to access a lot more fields, the performance difference could add up quickly so it may become significant enough.

I shared this in a CRMUG summit session previously, this is the first time I put the idea down in writing. I hope this is helpful, happy CRM (or 365) coding!

Archive

Tags