Retrieving the Attribute Names of CRM 2011 Entities

In CRM 2011, the CrmSvcUtil tool generates C# proxy classes for your CRM 2011 entities.

These classes are derived from the Entity class of the CRM SDK, the entities’ attributes are marked up with an AttributeLogicalName attribute which stores the attribute’s name in the database.

For queries, we need to list these attribute names, and it would be nice if the compiler used the data in the attributes to implement a type-safe compile-safe retrieval of attribute names by providing the properties of the C# classes.

Based on my code to retrieve property names from LinQ expressions, I wrote an extension method to retrieve the attribute names using the AttributeLogicalName attribute:

public static class EntityExtensions
  public static string GetAttributeName<T, P>(this T record, 
                          Expression<Func<T, P>> attribute) 
    where T : Entity
    MemberExpression memberExpression = 
    var member = memberExpression.Member;

    var nameAttributes = member.GetCustomAttributes(
      typeof(AttributeLogicalNameAttribute), true);
    if (nameAttributes != null && nameAttributes.Length > 0)
      var logicalName = 
        (nameAttributes[0] as AttributeLogicalNameAttribute)
      return logicalName;
    throw new ArgumentException(string.Format(
      "{0} is not a CRM property of entity {1}", 
      member.Name, typeof(T).Name));

We can then write a sample program like this

static void Main(string[] args)
  var account = new Account();
  Console.WriteLine(account.GetPropertyName(a => a.AccountId));
  Console.WriteLine(account.GetAttributeName(a => a.AccountId));
  Console.WriteLine(account.GetPropertyName(a => a.AccountNumber));
  Console.WriteLine(account.GetAttributeName(a => a.AccountNumber));

resulting in this output


Using this extension method, we can write a type-safe ColumnSet helper to provide the parameters for the built-in ColumnSet constructor:

public class ColumnSet<T> where T: Entity
  List<string> columns = new List<string>();

  public ColumnSet<T> Add<P>(Expression<Func<T, P>> expression)
    return this;

  public string[] Columns { get { return columns.ToArray(); } }

The .Add() method implements a Fluent interface as it returns the object, allowing for concatenation of .Add() calls:

var columns = new ColumnSet<Account>()
  .Add(a => a.AccountId)
  .Add(a => a.AccountNumber);

The result can be passed to the ColumnSet constructor:

var columnset = new ColumnSet(columns.Columns);

One Response to Retrieving the Attribute Names of CRM 2011 Entities

  1. Mikkel Kaas says:

    Much appreciated code sample. Very useful🙂
    No surprise really, but it also works in CRM 2013.

    I made the obvious extension, which makes making a ColumnSet somewhat easier:
    public static IEnumerable GetAttributeNames(this T record, params Expression<Func>[] attributes) where T : Entity
    return attributes.Select(a => GetAttributeName(record, a));

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: