Monthly Archives: May 2017

TCS Tools: Expressions Syntax (CRMContext object and Sequence function)

CRMContext is a special object that is available to you in the code expressions, and that provides some core properties / methods you can use to work with Dynamics.

Here is an example of a code expression that’s using CRMContext:

CRMContext.Target[“name”] = “First Account”;

This expression is going to set “name” parameter of the target record to “First Account”.

Let’s see what’s available there:

1. CRMContext.Target

For the Create/Update/Delete/Retrieve expressions, this is the actual entity record for which your expression is running. If you are familiar with plugins development, it’s what you would get in the plugin if you accessed context.InputParameters[“Target”]

CRMContext.Target[“name”] = “Test Account”;

For the RetrieveMultiple expressions, this is, actually, an EntityCollection. Which is the same as context.InputParameters[“BusinessEntityCollection”] in the plugins.


foreach(a in CRMContext.Target.Entities)
 a[“name”] = “Test”;

2. CRMContext.PreImage

For the Update/Delete expressions, this is how the entity looked like before the operation started.

if(CRMContext.PreImage[“name”] == CRMContext.Target[“name”]){




3. CRMContext.UserId

This is GUID of the user performing the operation


4. CRMContext.CreateRecord(string entityName)

You can use this function to create a new entity record:

newRecord = CRMContext.CreateRecord(“account”);


5. CRMContext.SaveRecord(Entity entity)

You can use this function to update an entity record. If you used CreateRecord to create that record in the first place, this call will be translated into a “Create” call to the organization service. Otherwise, it’ll be transalted into an “Update” call:



6. CRMContext.DeleteRecord(Entity entity)

You can use this function to delete an entity record:



7. CRMContext.DeleteRecord(Entity entity)

You can use this function to delete an entity record:



8. CRMContext.LookupRecord(entityName, attributeName, attributeValue)

You can use this function to lookup a record:

contact = CRMContext.LookupRecord(“contact”, “fullname”, “CRM Admin”);


9. CRMContext.QueryFetchXml(fetchXml)

You can use QueryFetchXml to run a fetchXml query:

contacts = CRMContext.QueryFetchXml(<YOUR FETCH XML>);
foreach(c in contacts)


12. CRMContext.IsTeamMember(TeamId, UserId)

You can use IsTeamMember function to verify user’s membership in a team:

if(CRMContext.IsTeamMember(teamId, userId))

13. There is, also, a Sequence(sequenceName, minimumCharacters, leadingCharacters) function that you can use to generate sequential id-s. This function is not in the CRMContext, though:

CRMContext.Target[“name”] = Sequence(“Account”, 5, “*”);

In the example above, “name” attribute of the current entity record will be populated with a new sequential id. That id will be generated for the “Account” sequence (it will be created if it does not exist), it will have at least 5 characters, and, if the number is not big enough, it will use “*” for the leading characters (so, for example, the first time you call it you’ll get *****1 as a result)

TCS Tools: Expressions Syntax (Introduction)

Here is what you should know about the expressions syntax to start working with them.

Solution entities:

  • TCS Expression – use it to create and register code expressions
  • TCS Number Sequence – works in combination with the Sequence function. Normally, there is no need to work with this entity directly. However, you can manually update “Next Value” attribute on the corresponding Number Sequence record if you want to move next number up or down for a particular sequence

What you can do:

  • You can introduce a variable without having to declare it (Ex: i = 5)
  • You can use while and foreach loops
  • You can use function syntax to introduce reusable code
  • You can use new operator as a constructor
  • You can access a lot of standard .NET framework classes and use them in y our expressions. This is done through reflection in a very generic manner, so there is no guarantee any particular class will be fully supported (you will have to test it, and, if it’s not working, I may need to look into why. Still no guarantee, though)
  • You can use “if/else”
  • You can access the record for which your expression is running through the built-in “target” variable
  • You can register your expression to run for “Update” (pre-op), “Create”(pre-op), “Delete”(pre-op), “Retrieve”(post-op), “RetrieveMultiple”(post-op)
  • You can use built-in CRMContext object
  • You can use Sequence function
  • You can raise an error with RaiseError function

What you don’t need to do:

  • You do not need to declare types

What you cannot do:

  • There are some limitations on what you can do with generic methods/types
  • You cannot define namespaces or classes
  • You cannot use try-catch
  • You cannot use “throw” operator, but you can use RaiseError function instead
  • You cannot access plugin context and/or organization service directly (working on it)


Below are some examples of the code you can put into the expressions

1. Using c# string functions

s = “testTESTtest”;
i = s.IndexOf(“TEST”);
j = s.IndexOf(“test”, i);

2. Using “if”

i = 0;
if(CRMContext.Target!= null)
i = 1;

3. Accessing current record attributes

CRMContext.Target[“name”] = “Has main phone #”;

4. You can access framework classes

i = Math.Abs(-1) + Math.Abs(-2);

5. You can access framework classes

i = Math.Abs(-1) + Math.Abs(-2);

6. You can use foreach with collections

a = 1;
foreach(b in CRMContext.Target.Attributes)
if(b.Key == “”tcs_integer””)
a = b.Key;

7. You can use constructors

a = new Money();
a.Value = new Decimal(10);
CRMContext.Target[“tcs_money”] = a;
8. You can define simple functions

function test(i, j)
return i+j;
9. You can use while loop

while(i < 20)
i = i+2;
10. You can use if/else

if(i < 25){
i = 25;
else i = 10;

11. You can use RaiseError to throw a regular InvalidPluginExcecutionException(hint: this helps a lot when debugging)

RaiseError(“Your message here”);

You can also use CRMContext object and Sequence function – read more..