For most of my development work in the last couple of years, I’ve stayed in the .NET 2.0 framework. Even though I moved to VS 2008 last year, I kept targeting the older framework. A couple of months ago, however, I really started doing all my projects in .NET 3.5. The main factor for me finally moving up is the ability to create Extension Methods. If you’re a regular user of helper classes, then you’ll really appreciate the ability to add methods to existing CRM SDK objects without having to implement a derived type.
Since I almost solely use Dynamic Entities, I found a few simple things where doing some extension methods would really making my life easier. None of these is particularly complicated or ingenious, but I think they’re pretty neat. Mainly all I’m doing is incorporating some basic helper functions.
I have a class file that I add to all my CRM projects which contains a helper class (CrmHelper) and a class called Extentions which contains all of my extension methods. For all examples, I’ll be demonstrating using the methods on a Dynamic Entity object I’ve named “entity”:
GetKeyValue()
Simply put, this function returns the guid value of the current Dynamic Entity object, if it does not have one, then it returns Guid.Empty.
Usage:
Guid keyVal = entity.GetKeyValue();
Here’s the code:
public static Guid GetKeyValue(this DynamicEntity entity)
{
string entityKeyName = entity.Name + "id";
Guid val = Guid.Empty;
if (entity.Properties.Contains(entityKeyName))
{
val = ((Key)entity[entityKeyName]).Value;
}
else if (entity.Properties.Contains("activityid"))
{
val = ((Key)entity["activityid"]).Value;
}
return val;
}
All the function does is check for the entity id attribute (entity name + “id”), if it’s not found, then we check to see if it contains “activityid” (for the activity entities). Then we just return the value of the property.
GetFullRecord()
If you’ve done any amount of plug-in programming, you probably know that the Dynamic Entity used in the plugin context only contains attributes that have changed. Therefore, it is often necessary to call back into CRM to get the full record. I decided to utilize my CrmHelper class and use an extension method and make getting the full record a simple call from the plug-in.
Usage:
DynamicEntity fullEntity = entity.GetFullRecord(helper);
Code:
public static DynamicEntity GetFullRecord(this DynamicEntity entity, CrmHelper helper)
{
// get full entity record
return helper.Retrieve(entity.Name, entity.GetKeyValue());
}
Pretty simple execution – I just do a quick retrieve and return the resulting entity.
An enhancement to this function would be to have it save the full record back to the original dynamic entity, so you can avoid creating a new object for the full entity.
Usage:
entity.GetFullRecord(helper);
Code:
public static void GetFullRecord(this DynamicEntity entity, CrmHelper helper)
{
// get full entity record
entity = helper.Retrieve(entity.Name, entity.GetKeyValue());
}
These are just a couple of examples of how using extension methods can really help simplify your CRM programming. Cheers!

Here is my samples (based on KeyProperty):
public static KeyProperty Key(this DynamicEntity dynamicEntity)
{
foreach (Property prop in dynamicEntity.Properties)
{
if (prop is KeyProperty)
{
return prop as KeyProperty;
}
}
throw new KeyNotFoundException("В коллекции свойств сущности нет свойства типа KeyProperty");
}
Also I use similar approach for Lookup fields:
public static BusinessEntity Entity(this Lookup lookup, string typeName)
{
return _service.Retrieve(
(lookup.type ?? typeName),
lookup.Value,
new AllColumns());
}
Note, you must pass the type of Lookup field, since "type" field often is null...
Posted by: Vlad | November 09, 2009 at 03:27 AM
The obvious type would be AttributeCollection but would move unnecessary casting in some of the other extension methods. The types will be MetaTable for the table permissions extension method and MetaColumn for the others and any casting will then be hidden in the extension methods themselves.
Posted by: 8gb usb drive | December 21, 2009 at 02:44 AM