Skip to content

IOrganizationService Extensions

Artem Grunin edited this page Mar 24, 2026 · 25 revisions

IOrganizationService Extensions

Set of extension methods for IOrganizationService base class. Most of these are simple overrides of existing methods which take EntityReference or Entity instead of separate Id and LogicalName parameters. But you also can take some advantage of alternative keys support or working with large datasets.

Associate & Disassociate

Associate & Disassociate methods override. Take EntityReference (instead of separate Id + LogicalName) input parameter.

Alternative keys are supported since v 1.0.43

public void Associate(EntityReference primaryEntity, Relationship relationship, EntityReferenceCollection relatedEntities);
public void Associate(EntityReference primaryEntity, Relationship relationship, IList<EntityReference> relatedEntities);
public void Associate(EntityReference primaryEntity, String relationshipName, EntityReferenceCollection relatedEntities);
public void Associate(EntityReference primaryEntity, String relationshipName, IList<EntityReference> relatedEntities);

public void Disassociate(EntityReference primaryEntity, Relationship relationship, EntityReferenceCollection relatedEntities);
public void Disassociate(EntityReference primaryEntity, Relationship relationship, IList<EntityReference> relatedEntities);
public void Disassociate(EntityReference primaryEntity, String relationshipName, EntityReferenceCollection relatedEntities);
public void Disassociate(EntityReference primaryEntity, String relationshipName, IList<EntityReference> relatedEntities);

Delete

Delete method override. Take EntityReference (instead of separate Id + LogicalName) input parameter.

Alternative keys are supported since v 1.0.29

public void Delete(EntityReference reference);
public void Delete(Entity entity);

Delete by Alternative key

Delete method override. Deletes using Alternative keys instead of Id. This one use Execute under the hood

public void Delete(string logicalName, KeyAttributeCollection keyAttributeCollection);
public void Delete(string logicalName, string keyName, object keyValue);

Introduced in version 2.8.0

public void Delete<T>(Guid id) where T : Entity;
public void Delete<T>(string keyName, object keyValue) where T : Entity;
public void Delete<T>(Expression<Func<T, object>> keyName, object keyValue) where T : Entity;

usage:

//We assume that AccountNumber attribute is added to Alternative key configuration
service.Delete<Account>(a=> a.AccountNumber, keyValue: 42);
service.Delete<Account>("accountnumber", keyValue: 42);

//this one is using delete by id + entity name under the hood
service.Delete<Account>(id);

Execute<T>

Introduced in version 1.0.38

Generic Execute methods override. Returns response as the specified type. Requires the same amount of typing as any other form of casting. Useless.

public T Execute<T>(OrganizationRequest request) where T : OrganizationResponse;

Execute (Multiple)

Introduced in version 1.5.0 deprecated in version 2.2.0

Execute batch of requests using ExecuteMultipleRequest while taking care of butch size

Warning: NEVER use this extension as well as ExecuteMultipleRequest itself in Plugin code. It can lead to deadlocks and performance issues

In other cases it should significantly improve performance compared to the ordinary for or Parallel.For loops

public IEnumerable<ExecuteMultipleResponse> Execute(IEnumerable<OrganizationRequest> requests, int batchSize = 1000, ExecuteMultipleSettings settings = null);

This is experimental feature:

You can use ExecuteMultipleResponse.GetRequests() or ExecuteMultipleResponse.GetRequest(ExecuteMultipleResponseItem item) to access actual OrganizationRequest objects used to perform the operation. It may be useful to understand status of each particular request

Retrieve

Retrieve method override. Take EntityReference (instead of separate Id + LogicalName) input parameter.

Alternative keys are supported since v 1.0.29

public Entity Retrieve(EntityReference reference, ColumnSet columnSet);
public Entity Retrieve(EntityReference reference, params String[] columns);
//introduced in v 2.11.0
public Entity Retrieve(RetrieveRequest request)

Retrieve<T>

Generic version of Retrieve.

public T Retrieve<T>(EntityReference reference, ColumnSet columnSet) where T : Entity;
public T Retrieve<T>(EntityReference reference, params String[] columns) where T : Entity;
//introduced in v 2.11.0
public Entity Retrieve(RetrieveRequest request)

Introduced in version 2.8.0

public T Retrieve<T>(Expression<Func<T, object>> keyName, object keyValue, params Expression<Func<T, object>>[] columns) where T : Entity;
public T Retrieve<T>(Guid id, params Expression<Func<T, object>>[] columns) where T : Entity;
public T Retrieve<T>(EntityReference reference, params Expression<Func<T, object>>[] columns) where T : Entity;

usage:

//We assume that AccountNumber attribute is added to Alternative key configuration
var account = service.Retrieve<Account>(a=> a.AccountNumber, keyValue: 42, a=> new { a.PrimaryContactId, a.Name });

//this one is using retrieve by id + entity name under the hood
var account = service.Retrieve<Account>(id/reference, a=> a.PrimaryContactId, a.Name);

Retrieve by Alternative key

Retrieve method override. Take EntityReference instead of Id. This one use Execute under the hood

public Entity Retrieve(string logicalName, KeyAttributeCollection keyAttributeCollection, ColumnSet columnSet);
public Entity Retrieve(string logicalName, string keyName, object keyValue, ColumnSet columnSet);
public Entity Retrieve(string logicalName, string keyName, object keyValue, params string[] columns);

Retrieve<T> by Alternative key

Generic version of by Alternative key. This one use Execute under the hood

public T Retrieve<T>(string keyName, string keyValue, ColumnSet columnSet) where T : Entity;
public T Retrieve<T>(string keyName, string keyValue, params String[] columns) where T : Entity

RetrieveMultiple

Introduced in version 1.0.38

RetrieveMultiple methods override. Returns all pages using callback or 'yield' iterator. This implementation should be very cost effective as new pages are loaded on demand (lazy loadind). You also can use callback function to access original EntityCollection properties. Callback function is executed on each page load.

Warning: Callback is executed only then you use iterator.

public IEnumerable<Entity> RetrieveMultiple(QueryBase query, Action<EntityCollection> callback = null);
public IEnumerable<Entity> RetrieveMultiple(FetchExpression query, Action<EntityCollection> callback = null);

Introduced in version 1.0.38

public IEnumerable<Entity> RetrieveMultiple(string fetchXml, Action<EntityCollection> callback = null);
public EntityCollection RetrieveMultiple(string fetchXml);

RetrieveMultiple<T>

Introduced in version 2.8.0

Warning: Proxy types should be enabled for IOrganizationService client for this method to work efficiently. Otherwise additional allocations will occur for each retrieved entity. In case of using in plugin, make sure that plugin assembly has assembly level attribute [assembly: Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute()] set. It may be lost if you are using assembly merging. Please look at project main page for instructions.

public IEnumerable<T> RetrieveMultiple<T>(QueryBase query, Action<EntityCollection> callback = null) where T : Entity;
public IEnumerable<T> RetrieveMultiple<T>(FetchExpression query, Action<EntityCollection> callback = null) where T: Entity;

Upsert

Introduced in version 1.0.42

A shortcut for Upsert message

public EntityReference Upsert(Entity entity);

Update

Introduced in version 1.2

Update method override. Take ConcurrencyBehavior enum as second parameter.

public void Update(Entity entity, ConcurrencyBehavior concurrencyBehavior);

Execute (Multiple)

Introduced in 2.2.0

Execute batch of requests using ExecuteMultipleRequest while taking care of butch size

Warning: NEVER use this extension as well as ExecuteMultipleRequest itself in Plugin code. It can lead to deadlocks and performance issues

In other cases it should significantly improve performance compared to the ordinary for or Parallel.For loops

public IEnumerable<ExecuteMultipleOperationResponse> Execute(IEnumerable<OrganizationRequest> requests, int batchSize = 100, ExecuteMultipleSettings settings = null, Action<OrganizationRequestCollection, ExecuteMultipleResponse> callback = null)

Execute (Query)

Introduced in 2.2.0

Runs query and executes action for each retrieved Entity using ExecuteMultipleRequest

Warning: NEVER use this extension as well as ExecuteMultipleRequest itself in Plugin code. It can lead to deadlocks and performance issues

In other cases it should significantly improve performance compared to the ordinary for or Parallel.For loops

Warning: this method will run immediately after the call and may take a lot of time to complete depending on the amount of data and particular OrganizationRequest performance. You can use CancellationToken to cancel operation at any time.

public void Execute(QueryBase query, Func<Entity, OrganizationRequest> toRequest, ExecuteMultipleSettings settings = null, int batchSize = 100, Action<ExecuteMultipleOperationResponse> onResponse = null, Action<ExecuteMultipleProgress> onProgress = null, CancellationToken cancellationToken = default)

UpdateChanged

Introduced in 2.4.0

Updates only changed attributes of the record

Warning: This method will execute Retrieve operation before performing Update. Consider using Entity.RemoveUnchanged if you already have as-is and to-be entity instances

public void UpdateChanged(Entity entity);

RetrieveSingle

Introduced in 2.7.0

Retrieves single query result as Entity or throws InvalidOperationException if query returns nothing or more than one record

public Entity RetrieveSingle(QueryBase query)

RetrieveSingle<T>

Introduced in 2.7.0

Retrieves single query result as strongly typed entity object or throws InvalidOperationException if query returns nothing or more than one record

public T RetrieveSingle<T>(QueryBase query) where T : Entity

RetrieveSingleOrDefault

Introduced in 2.7.0

Retrieves single query result as Entity or null if query did not return results

public Entity RetrieveSingleOrDefault(QueryBase query)

RetrieveSingleOrDefault<T>

Introduced in 2.7.0

Retrieves single query result as strongly typed entity object or null if query did not return results

public T RetrieveSingleOrDefault<T>(QueryBase query) where T : Entity