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 = 
      (MemberExpression)attribute.Body;
    var member = memberExpression.Member;

    var nameAttributes = member.GetCustomAttributes(
      typeof(AttributeLogicalNameAttribute), true);
    if (nameAttributes != null && nameAttributes.Length > 0)
    {
      var logicalName = 
        (nameAttributes[0] as AttributeLogicalNameAttribute)
        .LogicalName;
      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

AccountId
accountid
AccountNumber
accountnumber

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)
  {
    columns.Add(EntityExtensions.GetAttributeName(default(T), 
                                                  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:

WordPress.com Logo

You are commenting using your WordPress.com 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: