Line Coverage | Branch Coverage |
---|---|
This is a library for updating only those fields that really changed during a transaction in Dynamics CRM / Dynamics365.
This library can be used in CRM Plugins / Workflow Activities and in code of external applications. It is distributed as source file, so you don't need to merge DLLs. It does not include references / dependencies to any CRM SDK, so you can just install it and choose the CRM SDK that you need yourself. All CRM versions from 2011 to 365 are supported, just include the one you need to your project.
When sending updates on entities, it is a best practice, to only include those fields in your update object, that really need to be updated. When using the IOrganizationService, this could look somewhat like this
var updateRecord = new Entity
{
Id = oldRecord.Id,
LogicalName = oldRecord.LogicalName,
Attributes = new AttributeCollection
{
/// Your updates
}
};
service.Update(updateRecord);
This can get messy and is somewhat verbose. You could also use the CrmContext / OrganizationServiceContext if you're programming early-bound, but this library aims to work early- and late-bound, as well as being lightweight.
- For being able to really only update changed fields and prevent update loops, all fields that are going to be updated should be set in the initial state. So if you're retrieving data for updates, you should at least include all columns that you are going to update. This becomes especially relevant when setting fields to null: If a field was not added to the initial state and is set null, this is handled as noop and no update is sent.
This library is available as Nuget Package. It is distributed as source file, so you can use it in Plugins and Workflow Activities without having to merge DLLs.
You can initialize the context to track one of your objects, do any change you like to it, and call the context to get a diff object:
using(var updateContext = new UpdateContext<Contact>(contact))
{
contact.FirstName = "Bilbo";
Contact updateObject = updateContext.GetUpdateObject();
if (updateObject != null)
{
service.Update(updateObject);
}
}
In above code, you need to check the updateObject for null yourself. If you want to send an update directly, you can do the following:
using(var updateContext = new UpdateContext<Contact>(contact))
{
contact.FirstName = "Bilbo";
bool updateSent = updateContext.Update(service);
}
When using Transaction Requests, you might want to get an UpdateRequest for adding it to your transaction:
using(var updateContext = new UpdateContext<Contact>(contact))
{
contact.FirstName = "Bilbo";
UpdateRequest updateRequest = updateContext.GetUpdateRequest();
}
Upon initialization, the entity you passed in gets deep copied internally. On each call to get or send updates, the cloned object is compared to the working object that is still referenced and an update object is built, which only contains the properties that were updated in the working object.
If you want to build this library yourself, just call
.\build.cmd