CRM 2013 – using Entity.GetAttributeValue instead of Entity.Contains

I found myself writing this tried and tested code, which I have written many times before

if (entity.Contains("salutation"))
{
     title = ( string)entity.Attributes["salutation"];
}

before you can get a value from the entity attributes you need to check the field is included in the list of parameters. I traditionally use to do this using entity.Contains(“fieldname”), if the field specified exists in the list of parameters it will return true. The reason this works is because CRM doesn’t pass null values in the parameter list, so if its null it won’t exist.

Often in code you will lines and lines of Entity.Contains code, checking the field exists before assigned the value.

Is there a better way

I remember an excellent post featured on CRM MCC Guido on his blog CRM Answers
Entity.GetAttributeValue and ActivityParty

The article was about using Entity.GetAttributeValue and in this blog he linked to an excellent and detailed explanation of how Entity.GetAttributeValue works from CRM MVP Dave Berry

Entity.GetAttributeValue Explained

I had a classic case of reading how to do something in a better way but automatically doing it the way I always did it, except I now had a chance to do it differently and that’s what I did.

 

What is the Entity Class

The Entity class is the base class in CRM development and this class holds some key details about what entity it is

LogicalName – logical name of the record e.g. contact,account, lead
Id – ID of the record

The other important values are the Attributes. The attributes are a collection of attributes, e.g. all the fields in the entity/record.

What is the difference between an entity and a record

Entity

The entity e.g. account, contact, lead.  This is the design of an entity but doesn’t hold any values.  I would liken this to an object and an instance of an object.

Record

A record is an entity but with values, e.g. someone has created a New contact and this creates an instance of an entity (the design) and makes a record with individual values (e.g. name = Hosk, description = marvellous);

It uses object to enable it hold the various different variable types possible, it will mean if you are using late binding you will need to cast the values into the type you are expecting.

 

Trying Entity.GetAttributeValue

I thought I would try it out because it would save me wrapping if statements round things and seemed a better way to do things.

initially I removed the contains if statement and I got a variable doesn’t exist type error, hmm this isn’t meant to happen , I then realised it was a user error

I actually hadn’t typed it in but just removed the if
title = (string)entity.Attributes[ “title”];

I then added the proper method
title = entity.GetAttributeValue(“title”);

 

When developing I usually test my plugin code by making my plugin code take a iOrganisationService instance and an entity and put these in a separate class. This means the plugin can call my class but more importantly it means I can call this class by creating an iOrganisationService and an Entity object and not worry about any of the other plugin stuff. This enables me to call my new code in a console app which creates an IOrganisationService connected to the Dev environment and then do a service.Retrieve(“contact”, guid, columnset);

So I kicked of my console app and this retrieved a contact record and selected the title record and in this case the value was null and the code set the string title variable to null.

 

So I used this to retrieve a OptionSetValue and string and it worked fine.

it’s important to note this will bring null back if there is no value or the value is null.

Also remember for some types it will bring back the default value if something doesn’t exist and this might not be what your code is expecting.  In Dave’s blog he has a handy table

Type Return
Numerical (int, decimal, double) 0
Boolean false
DateTime DateTime.MinValue
Guid Guid.Empty

 

Why isn’t Hosk using Early binding

A question you are asking is why is the Hosk using Entity instead of an early bound class like Contact or Lead.  Great question, I’m glad you asked 🙂

The reason I am using the entity class is because the plugin was going to run on the contact and lead entity and maybe some other entities in the future.  The fields had he same name on the different entities, this enabled me to write the code (using Entity) which would work on both Contact and Lead.

5 thoughts on “CRM 2013 – using Entity.GetAttributeValue instead of Entity.Contains

  1. nicobrandl March 7, 2015 / 2:19 am

    Hi, Ben, great post. I’d like to point out about the performance impact of using early bound.
    From my personal expirience, the execution time for plug ins using late bound is lower than those using early bound.
    Another side effect of using early bound is the size of the output assembly: in case of generating the EF file for all the entities is about 5 to 7 MB with early bound. When developing plug-ins using early bound the size of an assembly usually is in the order of KBs.

    Cheers

    Like

    • Hosk March 7, 2015 / 9:22 am

      I haven’t found using early bound code really has much effect on the speed of a workflow and the reduced errors and ease of understanding the code is worth it.

      If you have a big CRM solution then you will create big entity files so I would recommend only creating an entity file with the entities referenced by your plugin. This will speed up creating the file and the size of the plugin.

      https://xrmearlyboundgenerator.codeplex.com/

      Like

  2. RAJEEV December 14, 2016 / 4:30 pm

    I have one scenario where one button and dialog pointing same plugin. The functionalities to be done by dialog and button are different how can I differentiate that? Please help me. (CRM2015onpremise)

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.