Working with OrganizationService – Create, Retrieve and RetrieveMultiple

In the previous blog post, we created Console application in Visual Studio in which we added all necessary assemblies required to connect to CRM data. We created object of OrganizationService which implements the interface of IOrganizationService.

You can read more about it here: Working with organization data outside the Dynamics CRM – Part 1

In this post, we will explore three IOrganizationService methods in depth – we will see what they do, what input parameters they take, what they return and what is the best practice of using them. Those methods are: Create, Retrieve and RetrieveMultiple. In the next blog post we will discuss the rest of them: Update, Delete, Associate, Disassociate and Execute.

 

Create

First method is Create method. It creates new entity record in CRM. Let’s look at its definition:

Guid Create(Entity entity);

It takes entity object as input parameter, creates equivalent record in CRM and it returns Guid of newly created record. If any error happens in between, it throws an exception, so it is crucial to call it inside the try-catch block. There is a whole variety of possible reasons for exception: from broken connection to CRM to attempt to create record of non-existing entity or record of existing entity, but with non-existing fields. We will explore these kind of faults in some of the next posts.

Let’s create some entity object, specify its fields’ values and that using that entity object, call Create method and create equivalent entity record.

try {
     string con = "Url=https://URL; Username=USERNAME; Password=PASSWORD;"; Microsoft.Xrm.Client.CrmConnection connection = Microsoft.Xrm.Client.CrmConnection.Parse(con);
     using (Microsoft.Xrm.Client.Services.OrganizationService orgService = new Microsoft.Xrm.Client.Services.OrganizationService(connection)) {
          Entity account = new Entity("account");
          account["name"] = "Non-existing company";
          account["description"] = "This company does not exist.";
          orgService.Create(account);
     }
}
catch (Exception e) {
     Console.WriteLine(e.Message);
}

When creating Entity object, it is required to specify the logical name of the entity and the best practice is to do that in the constructor of the class, just as we did in the example. When specifying the values of fields, in this case account fields, be aware of using real names, defined in CRM, and NOT schema name nor display name. Therefore, it is “name” and not “Account Name”. Also, you don’t need to determine Id of the record if you don’t want to use something specific – CRM will do that on its own.

Furthermore, take care of the business required fields, such as “name” in account entity. Truth is that IOrganizationService will let you create entity records without specifying values for business required fields and those kind of records will appear in CRM, but it is highly discouraged practice. So, keep in mind that you definitely should specify the values for all business required fields.

 

Retrieve

The next method is Retrieve method. As the name itself implies, it is used for retrieving single entity from CRM data into your C# based project. Definition of the method is as follows:

Entity Retrieve(string entityName, Guid id, ColumnSet columnSet);

As input parameters it takes entityName, which is string stating name of the entity that is queried (account, lead etc.), id of the entity record (which is Guid type) and ColumnSet object. ColumnSet is class from XRM SDK library which is used to specify set of fields/columns when querying is done. It has constructor with the following definition:

public ColumnSet(params string[] columns);

which obviously takes as input parameter array of string values where each string value represents one column / field of the entity. Later on, new fields can be added by using some of the following two methods of ColumnSet class:

       public void AddColumn(string column);
       public void AddColumns(params string[] columns);

Also, alternative construtor can be used:

public ColumnSet(bool allColumns);

and when „true“ value is passed, ColumnSet object will assume that you want to retrieve all fields.

So, Retrieve method call is completed with three parameters: entity in which we are searching for the record, Id of specific record we want to retrieve and set of fields we want to retrieve on that specific record. If record exists, Retrieve method will return Entity object with set attributes as defined with ColumnSet object. If record doesn’t exist, method will throw an exception with message that entity record with specified Id does not exist.

Let’s look at the example in which we will retrieve existing record and try to retrieve non-existing one.

try {
     string con = "Url=https://URL; Username=USERNAME; Password=PASSWORD;"; Microsoft.Xrm.Client.CrmConnection connection = Microsoft.Xrm.Client.CrmConnection.Parse(con);
     using (Microsoft.Xrm.Client.Services.OrganizationService orgService = new Microsoft.Xrm.Client.Services.OrganizationService(connection)) {
          Entity account = new Entity("account");
          account["name"] = "Non-existing company";
          account["description"] = "This company does not exist.";
          orgService.Create(account);

          Entity retrivedAccount1 = orgService.Retrieve("account", id, new Microsoft.Xrm.Sdk.Query.ColumnSet(new string[] {"name", "description"});
          Console.WriteLine(retrivedAccount1["name"].ToString());
          Console.WriteLine(retrivedAccount1["description"].ToString());

          Entity retrivedAccount2 = orgService.Retrieve("account", Guid.NewGuid(), new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
     }
}
catch (Exception e) {
     Console.WriteLine(e.Message);
}

 

Retrieve Multiple

Following method that we will take a look at is RetrieveMultiple method. It is used for retrieving a collection of entities based on certain query. It requires definition of set of criteria that would determine which records will enter to the retrieved collection.

Definition of the method is as follows:

EntityCollection RetrieveMultiple(QueryBase query);

It takes query as input parameter. QueryBase is an abstract class and one of derived classes is QueryExpression from Microsoft.Xrm.Sdk.Query library. QueryExpression will determine which entity to query, which columns to retrieve and criteria based on which it will select records to include in retrieved entity collection. We will firstly set entity name to account and determine columns by ColumnSet (taking all account’s columns).

QueryExpression query = new QueryExpression();
query.EntityName="lead";
query.ColumnSet = new ColumnSet(true);

Now we need to specify criteria by Criteria attribute of QueryExpression. Criteria is defined by FilterExpression object whose class is also part of previously mentioned library. FilterExpression should be understood as collection of conditions, each added through FilterExpression’s method of AddCondition. It also has method AddFilter, so that it can take child FilterExpression and all its conditions. Condition is defined by object of ConditionExpression class. It has five different constructor definitions, but the following is the one you would probably need the most:

public ConditionExpression(string attributeName, ConditionOperator conditionOperator, object value);

AttributeName is name of the entity’s field. ConditionOperator is enumerable with many values such as: greater than, equal, not equal etc. And “value” is object typed, meaning that it could become anything – from null, across primitives, to any complex type or entity’s attribute. If you are using operators such as “In” or “between”, you would probably need some collection of values on the right side of this condition. Then you would need one of these constructors:

public ConditionExpression(string attributeName, ConditionOperator conditionOperator, params object[] values);

or

public ConditionExpression(string attributeName, ConditionOperator conditionOperator, ICollection values);

Finally we have all set for complete QueryExpression object and we can call RetrieveMultiple method. The method returns EntityCollection objects, out of whose Entities attribute DataCollection of entities can be extracted. DataCollection can be iterated as any other collection (since it is derived from Collection class) or it can be converted to array of entities.

Let’s take a look at the example.

try {
     string con = "Url=https://URL; Username=USERNAME; Password=PASSWORD;"; Microsoft.Xrm.Client.CrmConnection connection = Microsoft.Xrm.Client.CrmConnection.Parse(con);
     using (Microsoft.Xrm.Client.Services.OrganizationService orgService = new Microsoft.Xrm.Client.Services.OrganizationService(connection)) {

           QueryExpression query = new QueryExpression();
           query.EntityName = "lead";
           query.ColumnSet = new ColumnSet(true);

           query.Criteria = new FilterExpression();
           ConditionExpression con1 = new ConditionExpression("lastname", ConditionOperator.Equal, "Kahrovic");
           ConditionExpression con2 = new ConditionExpression("firstname", ConditionOperator.In, new string[] { "Ajdin", "Edin"});
           query.Criteria.AddCondition(con1);
           query.Criteria.AddCondition(con2);

           DataCollection<Entity> entities = orgService.RetrieveMultiple(query).Entities;

           foreach (Entity lead in entities)
           {
                Console.WriteLine(lead["firstname"] + " " + lead["lastname"] + " satisfied all your criteria!");
           }
     }
}
catch (Exception e) {
     Console.WriteLine(e.Message);
}

That’s all for this blog post. In the following one we will explore the rest of IOrganizationService methods: update, delete, associate, disassociate and execute.