Wednesday 16 March 2011

ObjectTypeCode - String or Int

I came across a handy little feature today. I have tested this and it works in Crm 4.0 as well as Crm 2011. Funny how I never knew this before. It would not have changed the world, but it would have made the odd task a little easier.

It seems that it is possible to use the object type codes (1,2 etc) interchangeably as integers or strings ("account", "contact") in a QueryExpression (and everywhere else, I guess). Since the Object Type Codes are always stored as integers in the database, I assumed that they will always need to be queried as integers.

For example, if you want all the tasks that has an Account as a Regarding Object you'd need to know what the Object Type Code for Account is. Now anyone that has dabbled in Crm for a while will know that Account = 1 and Contact = 2, but all custom entities start at 10,000 and exporting customizations from one Organization to another does not mean that the custom entity would have the same code. So, in the example above, I would have done something like this, because I knew that the code of 1 will always represent an Account:

QueryExpression query = new QueryExpression()
{
EntityName = "task",
ColumnSet = new AllColumns(),
Criteria =
{
Conditions =
{
new ConditionExpression()
{
AttributeName = "regardingobjecttypecode",
Operator = ConditionOperator.Equal,
Values = new object[] {1}
}
}
}
};

But for custom entities I would have had to find the current code for the entity first and pass that through to the QueryExpression.

Turns out that you can actually pass the string equivalent as a value as well !!!

QueryExpression query = new QueryExpression()
{
EntityName = "task",
ColumnSet = new AllColumns(),
Criteria =
{
Conditions =
{
new ConditionExpression()
{
AttributeName = "regardingobjecttypecode",
Operator = ConditionOperator.Equal,
Values = new object[] {"account"}
}
}
}
};

Brilliant!!

Paul Reyneke

Sunday 13 March 2011

Transactional features in Crm 2011

One of the very handy features in Crm 2011 is the fact that plugins now execute within the transaction, not outside it anymore. This means that if an error occurs within a plugin that fires on Create of a record, the actions done by the code gets rolled back AND the actual record created to trigger this event is also rolled back. So no more duplicate records if a plugin fails and the user, thinking that the record did not create, resaves the record.

For more information on the pipelines in Crm 2011, see here.

All good and fine so far, we have the ability in the SDK to see whether we are inside a Transaction or not via the IPluginExecutionContext (context.IsInTransaction).

My problem is a little more complex, I need to also know whether we are in the Pre-Event or Post-Event of the plugin. We sometimes need to check whether a plugin is a pre or post event plugin.

In Crm4.0 we simply used the IPluginExecutionContext (context.Stage), so:

if (context.Stage == MessageProcessingStage.BeforeMainOperationOutsideTransaction)
{ ... }

My problem is that I could not find how to do the equivalent in Crm 2011. The actual stage property is of type int, but normally the SDK would give us a static class or enumerator to use here. In Crm4.0 it was the MessageProcessingStage.

The actual integer values of the 5 possible states are published, so I simply added a static class to my helper methods to allow for this. I find it a little annoying that the Crm SDK forces you to use the integer value here when adding a simple enumerator to the SDK would be simple... but oh well.