Traditionally, insert and update have always been separate requests in Dynamics CRM. The logic to identify whether a record has to be created or updated was always something the developers had to handle themselves. Once you have identified the action to perform, call the appropriate message.
The API enhancements introduced in Dynamics CRM 2015 Update 1 (Spring Update CRM Online), we have now been provided with a new Request/Message “UPSERT”. Note this message is currently not available for On-Premise systems and it requires the CRM Online organizations to be updated to 7.1.x.
How does UPSERT work?
For UPSERT to work, we need to use the concept of Alternate Keys that is also a new concept introduced in the Spring Update. To learn more about Alternate Keys you can check the article here. In the AlternateKeys, you provide the fields/value pairs to look for a matching record. You cannot use any combination of field/value pairs. The field/Value pair provided should be a part of an Altenate Key already defined for the entity.
Here is how we form the request
// Define the Alternate key which uniquely identifies the record
KeyAttributeCollection acckeys = new KeyAttributeCollection();
// Create Account entity object by specifying the entity logical name and Alternate key
Entity accountEntity = new Entity(“account”,acckeys);
// Specify fields to update
accountEntity["name"] = “Account 001″;
accountEntity["telephone1"] = “23457567”;
// Create Upsert request
UpsertRequest upreq = new UpsertRequest();
upreq.Target = accountEntity;
// Execute Upsert request
UpsertResponse response = (UpsertResponse)_service.Execute(upreq);
You first define the Alternate Key that is to be used as the match criteria. Make sure you pass this Key as a part of instantiating the entity object.
Next you go ahead and create an entity object just like you did previously.
When this request is executed, the API looks for the match based on the Keys provided. If a match is found, it internally send an Update request. The Update Plugins/Workflows if any registered would be executed.
If no matching record is found, it will internally call the Create request. The Keys are passed on as a part of the entity fields and the record created would also have the values automatically set for these fields. So in the above example, we have not explicity added AccountNumber to the Entity attribute collection. But since it has been provided as part of Alternate Keys collection, the newly created record would have the accountnumber set to “ASH001″. In this case, the Create plugins/workflows would be executed.
How to identify if it actually Inserted or Updated the record?
The UpsertResponse, provides you with the details on this. In the “UpsertResponse” we get the “RecordCreated” attribute set to “True” if the Create request was called and a new record was created. It is set to “False” if the record existed and was updated.
One thing which you can notice in the above Upsert operation is that there was no need to provide the Id field (GUID which uniquely identifies any record in Microsoft Dynamic CRM) i.e. “accountid” in case of Account entity for identifying the existing matching record and then perform Create or Update operation. We achieved this using the alternate key which uniquely identified if the record existed and thereby eliminated the overhead of retrieving existing record to check if the record already exists.
Upsert helps reduce the roundtrips required for explicit search requests that was otherwise used. This could be widely used in scenarios where data needs to be integrated with external systems and ID/GUID is very rarely the match criteria. Make sure to define the Keys before you use them as part of this request.