The other day my friend Raj (
@RajYRaman) retweeted a post from Dynamics CRM PFE Team about the best practice to let CRM to choose the Guid of new records instead of using
Guid.NewGuid():
http://blogs.msdn.com/b/crminthefield/archive/2015/01/19/the-dangers-of-guid-newguid.aspx
With
IOrganizationService object is very easy to get the Id of the new record, because it's the value returned by the
Create method independently if late bound or early bound is used:
IOrganizationService service = new OrganizationService(crmConnection);
// late bound
Entity lateAccount = new Entity("account");
lateAccount["name"] = "Late Bound Account";
Guid lateAccountId = service.Create(lateAccount);
// early bound
Account earlyAccount = new Account();
earlyAccount.Name = "Early Bound Account";
Guid earlyAccountId = service.Create(earlyAccount);
This works because Early Bound classes inherit from the
Entity class.
public partial class Account : Microsoft.Xrm.Sdk.Entity ...
But how we can get the Id of the records when we use the
OrganizationServiceContext in combination with the
AddObject and
SaveChanges methods?
Using
Guid.NewGuid() in order to specify the Id before creating the record was one of my mistakes when I first used Early Bound classes. My badly written code was:
IOrganizationService service = new OrganizationService(crmConnection);
XrmContext context = new XrmContext(service);
// WORST CODE EVER, DON'T DO THIS!
Account earlyAccount = new Account();
Guid badGeneratedId = Guid.NewGuid();
earlyAccount.Id = badGeneratedId;
earlyAccount.Name = "Early Bound Account";
context.AddObject(earlyAccount);
context.SaveChanges();
The reason was to avoid parsing the results of the
SaveChanges method in order to get the Id.
SaveChanges doesn't return
void but a
SaveChangesResultCollection object with the details of the save operation.
But checking the results is not necessary, in fact the
OrganizationServiceContext updates the tracked records adding the Guid value to the Id property. We just need to read the Id property
after the
SaveChanges:
Account earlyAccount = new Account();
earlyAccount.Name = "Early Bound Account";
context.AddObject(earlyAccount);
context.SaveChanges();
Guid crmGeneratedId = earlyAccount.Id;
MSDN Documentation (at least at the time I discover this) isn't so clear explaining this behavior, hope it helps!