Hesam Seyed Mousavi, October 5, 2015
The latest Microsoft Dynamics CRM 2015 Update 1 release (v7.1) introduces a number of platform enhancements. Alternate Key is one of the coolest features available in this release. The primary benefit of this feature is to provide an alternative way to identify a CRM record.
Traditionally we use CRM entity’s primary key field to identify a CRM record, which stores GUID values. This becomes a challenge when we try to integrate CRM data with third-party database or application systems, which might use some natural keys to identify a record. With the introduction of the Alternate Key feature in CRM 2015 Spring release, it makes our job much easier when writing data integration code.
Upsert is a term that’s often seen in a DBA’s textbook, but not in a CRM developer’s. Upsert stands for Update/Insert, it indicates that it could take either an Update or an Insert action depending on whether a match can be found when writing to the target system.
With the introduction of Upsert support to the new CRM release, it makes the platform even better.
To use the Upsert capability, you need to:
- Have a CRM 2015 Update 1 (v7.1) instance (CRM Online only at this moment) in order to utilize this new feature.
- Use CRM SDK 7.1.0-preview to compile the code.
- Create the Alternate Keys in CRM system using its customization tool or SDK (please refer to my other blog post for more detailed instructions on how to create Alternate Keys).
No more Special Messages for Special Fields
Microsoft Dynamics CRM uses a number of special fields for special purpose, those fields used to require using special SOAP messages in order to update them.
For instance, almost every CRM entity has statecode and statuscode fields which represent the status of CRM records. In order to update a CRM record’s status, you would have to use SetStateRequest message. Another example is the ownerid field which is available to all entities that are setup as a user-owned entity. In order to update ownerid field, you would have to use AssignRequest. The list goes on including similar fields such as:
- systemuser entity’s parentsystemuserid field (requires SetParentSystemUserRequest message to update the field)
- systemuser entity’s businessunitId (requires SetBusinessSystemUserRequest message to update the field)
- team entity’s businessunitid (requires SetParentTeamRequest message to update the field)
- businessunit entity’s parentbusinessunitid field (requires SetParentBusinessUnitRequest message to update the field)
- equipment entity’s businessunitid field (requires SetBusinessEquipmentRequest message to update the field)
Plugin Trace Logging
In the past, plugin debugging has been a very challenging task when working with CRM online environment, due to the lack of a proper way to log error trace information.
The good news is, CRM Online 2015 Update 1 release has introduced a new feature which allows you to turn on plugin trace logging, debugging plugin code for CRM online server is no longer such a daunting job.
Entity Change Tracking
In CRM integration projects, your business requirements often dictate that you should only retrieve those transaction records that have been recently created or modified in your source system since last integration. When your CRM system is the source, you would typically use CRM FetchXML query to pull data from the CRM system by comparing the record’s modifiedon field, which is not a solution that is reliable enough and may not perform well when the source entity has a significant number of records.
To address this particular challenge, CRM Online 2015 Update 1 release introduced the Change Tracking feature, which offers a reliable and efficient way to track transactional data changes for CRM entities.
Some Closing Notes
There are a few things that you should be aware when using this feature:
- The “Change Tracking” option is an entity-level setting. It has to be enabled for the entity before you can use RetrieveEntityChangesRequest to pull data. If the option is not enabled, and you try to use this feature, you will get an error message telling you “Entity: account isn’t enabled for change tracking” where account can be any entity name that you are working with.
- Due to the fact that the “Change Tracking” option works at entity level, you would need to keep track of the change token for each entity individually. There is no organization level tracking token.
- There is one special situation that you should watch out for. Suppose there is a newly added record after last pull and it was deleted before the new pull, you will get the record in the Delete result set, which you may not have knowledge about it.
- In the case that you have selected to return a lookup field, the field’s Name property is not returned.
- When change collection has more records than the page size that you have specified, you would have to page through the change collection.
- Based on my preliminary testing, it appears that CRM keeps multiple token versions, which is really nice. However, I imagine keeping too many versions on the server side would not make sense as each version would consume a certain amount of database space. There must be a limit in terms of how many versions are kept on the CRM server side. It could be either a time-based limit (say 90 days probably, which could still be a lot of change versions if I keep pulling from the server every 30 seconds) or a number-based limit. This is something that has yet to be confirmed.
- When you retrieve changes using this feature, you will get the records in their current status, the old values before the change are not returned.
- The user account needs to have organization level read (or so-called “Root Read”) privileges for the concerned entity in order to uses RetrieveEntityChangesRequest to retrieve changes.
- More details about this feature can be found at the CRM SDK documentation page: Use change tracking to synchronize data with external systems.
Data integrity is critical to business. Transactional support is one of the important ways to ensure data integrity, which is something that you often run into in your CRM data integration project. The introduction of “Transaction Batching” feature in CRM Online 2015 Update 1 release is one important step forward as it enables an important integration scenario, which was not possible in previous CRM versions.
The Transactional Batching feature works in the following all or none fashion.
You put a batch of multiple individual requests into one ExecuteTransaction request, which contain a collection of CRM records that you want CRM server to process as a batch.
You submit the ExecuteTransaction request to CRM server.
CRM server process each record in the batch in the sequence as they came in within a single db transaction.
If all records have been successfully processed, the whole batch is committed; otherwise if any of the record fails, the whole batch is rolled back (all or none fashion)
Some Closing Notes
- An ExecuteMultipleRequest can contain ExecuteTransactionRequest messages, and each ExecuteTransactionRequest is responsible for all records in its own batch by running them in one single transaction.
- An ExecuteTransactionRequest cannot contain any ExecuteTransactionRequest or ExecuteMultipleRequest messages. If you try to do so, you will get an error indicating “ExecuteMultiple or ExecuteTransaction Requests cannot be executed inside another ExecuteTransaction request!”
- CRM transactional batching request (ExecuteTransactionRequest) is constrained by the same limits that are imposed on ExecuteMultipleRequest.
- The maximum allowed batch size is 1000.
- CRM online has a throttling of 2 concurrent batch requests. If you try to send more than 2 simultaneous batch requests to CRM online server, you will get an error indicating the server is busy.
- In the case when an ExecuteMultipleRequest contains ExecuteTransationRequest messages, the batch size of the ExecuteMultiple request is calculated by the total of all individual items.
- The requests that make up the ExecuteTransactionRequest do not have to be of the same type. You can have a mix of CreateRequest, UpdateRequest messages in the same batch.
- In the case that you need transactional support when creating records for a master/detail scenario (such as salesorder, salesorderdetail entities), you should continue to use RelatedEntities approach. Using ExecuteTransactionRequest is not going to help in this particular case, as there is no way to establish the relationship since the master record’s ID is not known.
- Using ExecuteTransactionRequest means that the db transaction will take longer to commit, and it can block other operations in the system. So use it with discretion!
For more details about this feature, please check out CRM SDK documentation page: Execute messages in a single database transaction.
In your Microsoft Dynamics CRM environment, data changes could happen to the same record simultaneously due to the operations initiated by different system users or applications at the same time. Such concurrency situation could sometimes result in data loss. With the introduction of Optimistic Concurrency feature in CRM Online 2015 Update 1 release, we now have a way to detect whether the record has been changed since the last time it was retrieved, which can help mitigate such potential data loss.
The Optimistic Concurrency feature is made possible by the ConcurrencyBehavior option of UpdateRequest and DeleteRequest message.
New Query Operators
CRM query system has been further enhanced in CRM Online 2015 Update 1 release to support more datetime filtering operators.
Additional Older-than Operators
Older-than operators allow you to perform filtering against CRM date/time fields by returning the records that are older than the provided criteria. CRM Online 2015 Update 1 release added a few more older-than operators in addition to the olderthan-x-months operator which was available before this release.
Operator Allowed Values Supported Version
olderthan-x-minutes 1-1440 v7.1+
olderthan-x-hours 1-2000 v7.1+
olderthan-x-days 1-500 v7.1+
olderthan-x-weeks 1-100 v7.1+
olderthan-x-months 1-100 v3.0+
olderthan-x-weeks 1-100 v7.1+
olderthan-x-years 1-100 v7.1+
Note that olderthan-x-months may have been around even before v3.0.
Detect SDK Capabilities by Checking CRM Server Version
For all the latest and coolest features that we have illustrated in this blog series, they are only available in CRM Online 2015 Update 1 release. If you try to send any of the new SOAP messages to a server that has a lower version (including CRM 2015 on-premise), your code will break, as the feature is not supported. So we need a way to detect whether the server is capable of dealing with the new features.
The good news is, this is actually a relatively simple task, as CRM SDK has offered a RetrieveVersionRequest message which allows you to sniffer the server version.
The idea is, you use the RetrieveVersionRequest message to get the CRM server version, and check whether it is greater than 7.1 (which corresponds to CRM Online 2015 Update 1 release). If yes, you do things in the new way using the new SDK capabilities. Otherwise, you would use the old approach (if available).