Today I wrote a small piece of code in order to replicate the exact same data from a CRM instance to another keeping the same ID, it was an exercise because I had to copy only a couple of entities, otherwise I could use one of the several tools made for this kind of operation (like KingswaySoft).
While I was writing the code I arrived to the point where I need to map the fields, so I started to write the usual GetAttributeValue<string>, GetAttributeValue<EntityReference>, ...
And I asked myself:
"source and target attributes are always of the same type, what if I use object for the Generic?"
"something like newEntity["name"] = oldEntity.GetAttributeValue<object>("name"); works?"
With a bit of surprise I found that actually works, so in the end I wrote this piece of code.
Some notes:
While I was writing the code I arrived to the point where I need to map the fields, so I started to write the usual GetAttributeValue<string>, GetAttributeValue<EntityReference>, ...
And I asked myself:
"source and target attributes are always of the same type, what if I use object for the Generic?"
"something like newEntity["name"] = oldEntity.GetAttributeValue<object>("name"); works?"
With a bit of surprise I found that actually works, so in the end I wrote this piece of code.
Some notes:
- It uses CrmServiceClient, because there are two instances (source and target) one of them should contains the option RequireNewInstance = true;
- The UpsertRequest works also when the entity has the ID defined, and not only when the entity is defined using an alternate key syntax
- As suggested by Tinus Smith in his comment, if the purpose is to do an exact copy, it's not necessary to create the entityTarget and copy its values with GetAttributeValue<object>, instead the entitySource can be used directly inside the Target property of the UpdateRequest:
UpsertResponse response = (UpsertResponse)target.Execute(new UpsertRequest { Target = entitySource });
MigrateEntity(source, target, "new_entity", new List{ "new_name", "new_date", "new_lookupid" }); private static void MigrateEntity(CrmServiceClient source, CrmServiceClient target, string entityName, List<string> columns) { QueryExpression querySource = new QueryExpression(entityName); querySource.ColumnSet = new ColumnSet(columns.ToArray()); EntityCollection collSource = source.RetrieveMultiple(querySource); foreach (Entity entitySource in collSource.Entities) { try { Entity entityTarget = new Entity(entityName); entityTarget.Id = entitySource.Id; foreach (string column in columns) { entityTarget[column] = entitySource.GetAttributeValue<object>(column); } UpsertResponse response = (UpsertResponse)target.Execute(new UpsertRequest { Target = entityTarget }); } catch (Exception ex) { Console.WriteLine(ex.Message); } } }