Wednesday, November 04, 2015

Early Bound Updates Filling the Audit Log

Using early binding with the Dynamics CRM SDK allows you to write type safe code with intellisense reducing the chances of run time exceptions.  However it does have some unintended consequences as every field gets updated and not just the fields that have changed. This can cause the audit history to fill up with unnecessary changes and may also trigger workflows or plugins unexpectedly.

If you look at the sample code below which updates two contact records the first uses late binding and the second use early binding. In the late bound example the ColumnSet class is used to control which fields get returned and updated.  If I had the columnset constructor to true then all the fields would be returned and updated.

// Early Bound
Contact earlyContact = ctx.ContactSet.First(c => c.FullName == "early bound");
earlyContact.Telephone1 = "777 7777";

// Late Bound
QueryByAttribute querybyexpression = new QueryByAttribute("contact");
querybyexpression.ColumnSet = new ColumnSet("telephone1");
querybyexpression.Values.AddRange("late bound");
EntityCollection retrieved = service.RetrieveMultiple(querybyexpression);
var lateContact = retrieved[0];
lateContact["telephone1"] = "666 6666";

If you look at the audit history for each record only telephone1 field has been changed for the early bound record. The audit history for the early binding example has recorded changes to every field even though they clearly have not changed.

Updates from the UI only every update changed (dirty) fields. I have seen a colleague add a custom field called SDK to each entity they update which they check to determine if workflows and plugins should fire.


1 comment:

  1. Hi Joe, you can achieve the same with early binding:
    ctx.ContactSet.Where(c => c.FullName == "early bound").Select(r => new Contact() {Telephone1 = r.Telephone1, [add other attributes you need}).FirstOrDefault();