In this article I’d like talk about forcibly calculating Rollup fields using the Microsoft Dynamics CRM SDK. In the Dynamics CRM web client, rollup fields are refreshed/calculated by asynchronous System Jobs. However in the SDK, you can force calculate rollup fields instantly without waiting for the Systems Jobs to calculate them for you.
Let’s say you have a web portal where students enrol in one of the classes. The portal should show the total enrolled students. Whenever a student enrols, the Total Students field on the Class entity should aggregate the total enrolled students using the Count function.
Here is a simple relationship between the Class and the Entity.
This the definition of the Rollup field on the Class entity:
The following code implements the same scenario explained above.
private static void CalculateRollupDemo()
{
//create a class record
Entity classRecord = new Entity("new_class");
classRecord["new_name"] = ".Net C#";
Guid classId = service.Create(classRecord);
// create a student record and link it to the parent class
Entity student = new Entity("new_student");
student["new_name"] = "s1";
student["new_classid"] = new EntityReference("new_class", classId);
service.Create(student);
// create another student record and link it to the parent class
student["new_name"] = "s2";
student["new_classid"] = new EntityReference("new_class", classId);
service.Create(student);
// retrieve the class record from CRM
classRecord = service.Retrieve("new_class", classId, new Microsoft.Xrm.Sdk.Query.ColumnSet("new_totalstudents"));
// read the rollup field value
int totalStudents = classRecord.GetAttributeValue<int>("new_totalstudents");
// print the value of the rollup field
Console.WriteLine("Total Students (using Retrieve Message)={0}", totalStudents);
// create a request by passing an entity reference and the targeted rollup field name
CalculateRollupFieldRequest crfr = new CalculateRollupFieldRequest
{
Target = new EntityReference("new_class", classId),
FieldName = "new_totalstudents"
};
CalculateRollupFieldResponse response = (CalculateRollupFieldResponse)service.Execute(crfr);
// read the entity and value of the rollup field
classRecord = response.Entity;
totalStudents = classRecord.GetAttributeValue<int>("new_totalstudents");
// print the value of the rollup field
Console.WriteLine("Total Students (using CalculateRollupFieldRequest)={0}", totalStudents);
}
If you execute the above code, you’ll find that the console application prints the value of the rollup field two times. The first one prints zero and the second one prints two. The first time printed zero because the value was returned using a normal Retrieve Message. Since, the asynchronous job has not executed yet, then the value is still zero (default value). However, in the second example, the CalculateRollupFieldRequest instantly calculates the value by passing the entity name and the Rollup field name.