Retrieve multiple records from Dataverse

Currently being updated

The post describes several methods to retrieve multiple records from Dataverse / Dynamics 365

Retrieve data using C#

Query Expression

QueryExpression query = new QueryExpression
{
   EntityName = "systemuser",
   ColumnSet = new ColumnSet("fullname", "jobtitle"),
   Criteria= new FilterExpression
   {
      Conditions = 
      {
         new ConditionExpression
         {
            AttributeName = "fullname",
            Operator = ConditionOperator.Like,
            Values = { "%Smith%" }
         }
      }
   }
};

EntityCollection result = service.RetrieveMultiple(query);
if (result.Entities.Any()) {
   foreach (var user in result.Entities) {
      tracingService.Trace("QueryExpressions fullname = " + user.GetAttributeValue<string>["fullname"]);
   }
   tracingService.Trace("Full name = " + result.Entities[0].Attributes["fullname"] + " & Job title = " + result.Entities[0].Attributes["jobtitle"]);
}

FetchXML

On line 2 in the following code snippet, note:

  • $ enables string interpolation which allows for embedded variables such as {searchTerm}
  • @ makes the string verbatim

On line 5, note:

  • the pattern ‘%{searchTerm}%’ is a like condition
string searchTerm = "smith";
string fetchXml = $@"<fetch>
                        <entity name='systemuser'>
                           <filter>
                              <condition attribute='fullname' operator='like' value='%{searchTerm}%' />
                           </filter>
                        </entity>
                     </fetch>";
                                    
EntityCollection result = pluginContext.OrganizationService.RetrieveMultiple(new FetchExpression(fetchXml));

if (result.Entities.Count >= 1)
{
   List<String> systemUserNames = result.Entities.Select(r => r.GetAttributeValue<String>(SystemUser.Fields.FullName)).ToList();
   if (systemUserNames.Any())
      tracingService.Trace("FetchXML " + systemUserNames.FirstOrDefault());
}     

and another example

Entity caseEntity = new Entity(cpl_case.EntityLogicalName);
caseEntity[cpl_case.Fields.cpl_person] = new EntityReference(Contact.EntityLogicalName, personId);

string fetchXml = $@"<fetch top='1'>
                       <entity name='cpl_alias'>
                         <filter>
                            <condition attribute='cpl_person' operator='eq' value='{personId}' />
                            <condition attribute='cpl_aliastyperef' operator='eq' value='{(int)cpl_PersonNameType.Formal}' />
                         </filter>
                       </entity>
                    </fetch>";

EntityCollection aliasResults = OrganizationService.RetrieveMultiple(new FetchExpression(fetchXml));
if (aliasResults.Entities.Count == 0 || aliasResults.Entities[0].Id == Guid.Empty)
   return;
caseEntity[cpl_case.Fields.cpl_personnameid] = new EntityReference(cpl_alias.EntityLogicalName, aliasResults.Entities[0].Id);

LINQ

string searchTerm = "smith";
var systemUserNames = (from usr in OrganizationContext.SystemUserSet
                       where usr.FullName != null &&
                             usr.FullName.ToLower().Contains(searchTerm.ToLower())
                       select usr.FullName).ToList();

if (systemUserNames.Any())
{
    tracingService.Trace("LINQ " + systemUserNames.First());
}

Note: Early binding is required for this. In this example, there would need to be an early binding file for ‘SystemUser’

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Contoso.Common.Entities
{
	
   /// <summary>
   /// Person with access to the Microsoft CRM system and who owns objects in the Microsoft CRM database.
   /// </summary>
   [System.Runtime.Serialization.DataContractAttribute()]
   [Microsoft.Xrm.Sdk.Client.EntityLogicalNameAttribute("systemuser")]
   public partial class SystemUser : Microsoft.Xrm.Sdk.Entity, System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged
   {
      public static class Fields
      {
	       public const string FullName = "fullname";
       	 public const string PrimaryNameAttribute = "fullname";

	       /// <summary>
      	 /// Full name of the user.
      	 /// </summary>
	       [Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("fullname")]
      	 public string FullName
      	 {
	          [System.Diagnostics.DebuggerNonUserCode()]
		        get
	        	{
	       	     return this.GetAttributeValue<string>("fullname");			
		        }		
	       }
      }
   }
}

Retrieve data using TypeScript / JavaScript in Dynamics 365

Web API

Example 1

Xrm.WebApi.retrieveMultipleRecords("systemuser", "?$filter=contains(fullname, 'smith')").then(
   function success(results) {
      for (let i = 0; i < results.entities.length; i++) {
         let systemuserid = results.entities[i]["systemuserid"];
      }
   },
   function (error) {
      Xrm.Utility.alertDialog(error.message);
   });

Example 2

let formContext = executionContext.getFormContext() as any;
let userSettings = Xrm.Utility.getGlobalContext().userSettings;
let fetchXml = `<fetch>
                   <entity name = "team" >
                      <attribute name="cpl_centre" />
                      <link-entity name = "systemuser" from = "cpl_defaultteam" to = "teamid" >
                         <filter>
                            <condition attribute="systemuserid" operator = "eq" value = "${userSettings.userId.slice(1, -1)}" />
                         </filter>
                      </link-entity>
                   </entity>
               </fetch>`;
let query = "?fetchXml=" + encodeURIComponent(fetchXml);

Xrm.WebApi.retrieveMultipleRecords("team", query).then(
   function success(results) {
      if (results.entities.length > 0) {
         let centreEntityRef = [{
            id: results.entities[0]._cpl_centre_value,
            name: results.entities[0]["_cpl_centre_value@OData.Community.Display.V1.FormattedValue"],
            entityType: results.entities[0]["_cpl_centre_value@Microsoft.Dynamics.CRM.lookuplogicalname"]
         }];
         formContext.getAttribute(cpl_noncomplianceAttributes.cpl_centreid).setValue(centreEntityRef);
      }
   },
   function (error) {
      console.error(error.message);
   }
);

Figure 8 & 9 represents how Figure 7 can be updated to use a custom helper function setLookupValue(). For more information see Get and set a dataverse lookup column

Figure 9

Example 3

Figure 10

Further reading

Make XRM WebAPI calls appear synchronous

References

https://learn.microsoft.com/en-us/power-apps/developer/model-driven-apps/clientapi/reference/xrm-webapi/retrievemultiplerecords

https://learn.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.iorganizationservice.retrievemultiple?view=dataverse-sdk-latest