Use LINQ to construct a query


Applies To: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

The .NET Language-Integrated Query (LINQ) query provider in Microsoft Dynamics 365 (online & on-premises) uses standard LINQ syntax. The first step in creating a LINQ query is to identify the relevant entity types and the relationships between them. You can then specify the data source and the other query parameters.

The from clause is used to return a single “root” entity. The query provider can only return entities of a single entity type. The orderby and select clauses must reference this root entity. You can use join clauses to add entities with a relationship to the “root” entity.

In This Topic

LINQ operators

LINQ limitations

Filter multiple entities

LINQ operators

All LINQ query expressions have a similar format. The following table shows the most common clauses in a LINQ query expression when using the Microsoft Dynamics 365 LINQ query provider.

LINQ Operator



Obtain a data source (the from clause)

When using the generated service context and early binding, use the IQueryable entity set, such as AccountSet, in the generated context.

When not using the generated context, the CreateQuery method on the organization service context object gives you access to Microsoft Dynamics 365 entities.

Using the generated service context:

var query1 = from c in context.ContactSet
select c;

Using the CreateQuery method:

var query1 = from c in context.CreateQuery<Contact>()
select c;

join clause

The join clause represents an inner join. You use the clause to work with two or more entities that can be joined with a common attribute value.

from c in context.ContactSet
join a in context.AccountSet on c.ContactId equals a.PrimaryContactId.Id

Filtering (the where clause)

The where clause applies a filter to the results, often using a Boolean expression. The filter specifies which elements to exclude from the source sequence. Each where clause can only contain conditions against a single entity type. A composite condition involving multiple entities is not valid. Instead, each entity should be filtered in separate where clauses.

from a in context.AccountSet
where (a.Name.StartsWith("Contoso") && a.Address1_StateOrProvince == "WA")


The orderby operator puts the returned query attributes in a specified order.

var query1 = from c in context.CreateQuery<Contact>()   
    orderby c.FullName ascending   
    select c;
foreach ( var q in query1)   
    Console.WriteLine(q.FirstName + " " + q.LastName);   

select clause

The select clause defines the form of the data returned. The clause creates a column set based on the query expression results. You can also define an instance of a new object to work with. The newly created object using the select clause is not created on the server, but is a local instance.

select new Contact   
    ContactId = c.ContactId,
    FirstName = c.FirstName,  
    LastName = c.LastName,
    Address1_Telephone1 = c.Address1_Telephone1   

LINQ limitations

The LINQ query provider supports a subset of the LINQ operators. Not all conditions that can be expressed in LINQ are supported. The following table shows some of the limitations of the basic LINQ operators.

LINQ Operator



Represents an inner or outer join. Only left outer joins are supported.


Supports one from clause per query.


The left side of the clause must be an attribute name and the right side of the clause must be a value. You cannot set the left side to a constant. Both the sides of the clause cannot be constants.

Supports the String functions Contains, StartsWith, EndsWith, and Equals.


Not supported. FetchXML supports grouping options that are not available with the LINQ query provider. More information:  Use FetchXML aggregation


Supports ordering by entity attributes, such as Contact.FullName.


Supports anonymous types, constructors, and initializers.


The last operator is not supported.

skip and take

Supports skip and take using server-side paging. The skip value must be greater than or equal to the take value.


Not supported. FetchXML supports aggregation options that are not available with the LINQ query provider. More information:  Use FetchXML aggregation

Filter multiple entities

You can create complex .NET Language-Integrated Query (LINQ) queries in Microsoft Dynamics 365 and Microsoft Dynamics 365 (online). You use multiple Join clauses with filter clauses to create a result that is filtered on attributes from several entities.

The following sample shows how to create a LINQ query that works with two entities and filters the result based on values from each of the entities.

using (ServiceContext svcContext = new ServiceContext(_serviceProxy))
 var query_where3 = from c in svcContext.ContactSet
                    join a in svcContext.AccountSet
                    on c.ContactId equals a.PrimaryContactId.Id
                    where a.Name.Contains("Contoso")
                    where c.LastName.Contains("Smith")
                    select new
                     account_name = a.Name,
                     contact_name = c.LastName

 foreach (var c in query_where3)
  System.Console.WriteLine("acct: " +
   c.account_name +
   "\t\t\t" +
   "contact: " +

Using svcContext As New ServiceContext(_serviceProxy)
 Dim query_where3 = From c In svcContext.ContactSet _
                    Join a In svcContext.AccountSet _
                    On c.ContactId Equals a.account_primary_contact.Id _
                    Where a.Name.Contains("Contoso") _
                    Where c.LastName.Contains("Smith") _
                    Select New With {Key .account_name = a.Name,
                                     Key .contact_name = c.LastName}

 For Each c In query_where3
  Console.WriteLine("acct: " &amp; c.account_name &amp; vbTab &amp; vbTab _
                    &amp; vbTab &amp; "contact: " &amp; c.contact_name)
 Next c
End Using

See Also

Sample: Create a LINQ query
Sample: Complex LINQ queries
Build queries with LINQ (.NET language-integrated query)
Use late-bound entity class with a LINQ query
Blog: LINQPad 4 Driver for Dynamics CRM REST/Web API are available on CodePlex

Microsoft Dynamics 365

© 2016 Microsoft. All rights reserved. Copyright