Cloning a Record in Dynamics CRM 2011

Clone a Record in Microsoft Dynamics CRM 2011

Brian Kretchman

One request I often get from my clients is the ability to clone a record in Dynamics CRM 2011. Back in the CRM 4.0 days, this was done fairly easily by a handful of ISV products and custom JavaScript. The one kicker that would always stump me and my associates was the ability to clone a record along with its related records. For example, if you wanted to make a complete copy of an Order record, you must copy its Order Products as well. Otherwise, you don’t have a complete clone of that Order.

I solved this problem in CRM 4.0 by creating a .Net Class that could be added to my custom code projects whenever I needed to clone a record. The Class was built to be dynamic so that it could be used on any type of entity, including custom entities. By doing this, however, the Class would need to hit the metadata services to understand the data types of the fields it needed to copy. This, of course, led to performance issues. To make things work quickly, the Class would cache the metadata in an XML file on the application side and refer to it when it needed. This way, the first time a record is cloned with the Class, the action of cloning would also cache the metadata and take several minutes to complete. Once the metadata is cached, future calls to clone the same entity type would work a lot faster.

It was a handful of work to build this Class and when Dynamics CRM 2011 came along I wasn’t looking forward to reviewing and updating my many lines of code. It turns out, however, that I didn’t need to worry about it. Apparently, cloning records with related records can be done in CRM 2011 with just a few lines of creative code.

In the example below, we will be cloning a Dynamics CRM 2011 Order along with its Order Products using the Late-Bound CRM SDK model.

To begin, we need to add a reference to our Visual Studio Project for the System.ServiceModel and System.Runtime.Serialization from the .Net Framework 4.0 and the Microsoft.Xrm.Sdk and Microsoft.Xrm.Client dll files that come with the Dynamics CRM 2011 SDK. We will use the following classes in our project.

using System.Net; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Client; using Microsoft.Xrm.Sdk.Query; using Microsoft.Xrm.Client; using System.ServiceModel.Description;

We will need to create an instance of the OrganizationServiceProxy so we can Implement and use the IOrganizationService Interface for creating a new record. We will authenticate with CRM by passing the default credentials (we will assume that the current user has access to CRM). We will also need an Instance of the OrganizationServiceContext, so we can retrieve the Order Products from the Order to be cloned

ClientCredentials cred = new ClientCredentials(); cred.Windows.ClientCredential = (NetworkCredential)CredentialCache.DefaultCredentials;
Uri orguri = new Uri("http://[CRM Server]/[Organization]/XRMServices/2011/Organization.svc"); OrganizationServiceProxy _serviceProxy = new OrganizationServiceProxy(orguri, null, cred, null); IOrganizationService _service = _serviceProxy; OrganizationServiceContext context = new OrganizationServiceContext(_service);

Further along in the Dynamics CRM 2011 code, we will need the ability to change some attributes of our records, so we need to tell the OrganizationServiceContext not to track the entity. This way, we will not need to attach the Order entity to the OrganizationServiceContext.

context.MergeOption = MergeOption.NoTracking;

Next, we will need to create an Instance of a Sales Order Entity, so we can populate that object with all of the fields of the record we are cloning. By passing in the GUID of the record to be cloned and setting the ColumnSet to True (for all fields), we will accomplish this.

Entity order = new Entity("salesorder"); order = _service.Retrieve(order.LogicalName, new Guid("[GUID of Record to be Cloned]"), new ColumnSet(true));

This is where we start to clone in Dynamics CRM 2011. We need to get all the Order Products for the Order to be cloned by retrieving them with the OrganizationServiceContext. We do this by passing through the relationship name (“order_detail”). Once we have all of the Order Products, we can start the “creative” part by resetting each Order Product as if it were a brand new and unsaved record. We do this by removing the “salesorderdetailid”, “salesorderid”, and “salesorderstatecode” for each Order Product. Once we create the cloned Order, these fields will be correctly populated for us. We also want to give each Order Product ID the value of a brand new GUID so that CRM treats it as a new record.

foreach (Entity item in order.GetRelatedEntities(context, "order_details")) { item.Attributes.Remove("salesorderdetailid"); item.Attributes.Remove("salesorderid"); item.Attributes.Remove("salesorderstatecode"); item.Id = Guid.NewGuid(); }

Once we take care of the Order Products, we need to do the same thing to the Order itself by removing the “salesorderid” and giving the Order ID a brand new GUID.

order.Attributes.Remove("salesorderid"); order.Id = Guid.NewGuid();

And finally, we create a new Order record based on our newly configured Entity objects with the IOrganizationService Interface.


After completing these steps and running your code, you will see a brand new record that contains all of the fields and all of the Order Products as your original Order. Your code should run fairly quickly as well.

You can be more creative by cloning other related records in Dynamics CRM 2011 such as Other Contacts or changing the values of any of the fields for the new record. Whatever your record cloning goal may be with CRM 2011, the additional creative code is up to you.

Click here to learn more about Microsoft Dynamics CRM 2011.

Next Post