While working on a LINQ query using early-bound classes in a Dynamics 365 plugin, we encountered a familiar error.
“Could not find an implementation of the query pattern for source type. ‘Where’ not found”
At a glance, everything looked fine. The query was syntactically correct, and the early-bound class was generated properly.
After spending some time, we realized that the error message wasn’t due to the query or the early-bound class itself. It was because we forgot to include the following directive:
using System.Linq;
Without this, C# doesn’t recognize LINQ query methods like Where, Select, or ToList.
Adding this single line at the top of the file resolved the issue immediately, the LINQ query compiled and executed as expected.
MultiSelect OptionSet (Choices) fields in Dataverse provide a flexible way to store multiple values within a single field. However, querying and filtering these fields require different techniques depending on the approach used.
In this blog post, we will explore various ways to filter records based on the Skills field (cr1a7_skills), which has the following values:
Name
Value
C#
255780000
Java
255780001
Python
255780002
We have the Skills (choices) field in our Contact table.
The query is to fetch all the contact records where skills includes C# or Java.
Filtering Using FetchXML
FetchXML allows filtering MultiSelect Option Set fields using the contain-values operator.
Using QueryExpression, we can apply the ContainValues condition to filter Multi
var query = new QueryExpression("contact");
query.ColumnSet.AddColumns("fullname");
query.Criteria.AddCondition("cr1a7_skills", ConditionOperator.ContainValues, 255780000, 255780001);
Filtering Using OData (Web API)
OData allows filtering MultiSelect Option Set fields using the ContainValues function.
If you’re using the SQL4CDS tool in XrmToolBox, you can filter MultiSelect Option Set fields using LIKE conditions.
SELECT contactid,
fullname
FROM contact
WHERE statecode = 0
AND (cr1a7_skills = '255780000'
OR cr1a7_skills LIKE '255780000,%'
OR cr1a7_skills LIKE '%,255780000,%'
OR cr1a7_skills LIKE '%,255780000'
OR cr1a7_skills = '255780001'
OR cr1a7_skills LIKE '255780001,%'
OR cr1a7_skills LIKE '%,255780001,%'
OR cr1a7_skills LIKE '%,255780001'
);
Filtering Using LINQ (C#)
For LINQ queries, MultiSelect Option Sets must be processed as OptionSetValueCollection.
if (myServiceClient.IsReady)
{
using (var context = new OrganizationServiceContext(myServiceClient))
{
var skillValues = new List<int> { 255780000, 255780001 };
var allContacts = context.CreateQuery("contact")
.Where(c => c["cr1a7_skills"] != null &&
(int)c["statecode"] == 0)
.ToList();
var filteredContacts = allContacts
.Where(c => ((OptionSetValueCollection)c["cr1a7_skills"])
.Select(osv => osv.Value)
.Any(skill => skillValues.Contains(skill)))
.Select(c => new
{
ContactId = c["contactid"],
FullName = c.Contains("fullname") ? c["fullname"].ToString() : string.Empty
})
.ToList();
var result = filteredContacts;
}
}
We might get the below error while using LINQ to query Dataverse –
System.NotSupportedException: ‘The method ‘GroupJoin’ cannot follow the method ‘SelectMany’ or is not supported. Try writing the query in terms of supported methods or call the ‘AsEnumerable’ or ‘ToList’ method before calling unsupported methods.’
This error occurs because the GroupJoin method, which is essentially what happens during the into … syntax in LINQ, is not supported in the Dataverse/LINQ provider for Dynamics CRM. The issue is related to how the LINQ provider translates queries into FetchXML or SQL that the Dataverse understands. Specifically, nested joins or SelectMany (used by DefaultIfEmpty() in left joins) are not fully supported by the LINQ provider for Dataverse.
The GroupJoin and DefaultIfEmpty methods (used for left joins) result in queries that cannot be translated directly into FetchXML. The LINQ provider for Dataverse does not support all LINQ-to-Entities features, such as nested joins or advanced grouping logic. When you perform nested joins with DefaultIfEmpty() for left joins, the LINQ provider struggles to translate it into the underlying Dataverse query format, which is why the exception is thrown.
To fix it we can break the query into multiple steps as shown below.
However, here as we are fetching partial data into memory and combining it, it increases transfer and processing overhead and can take a long time to process based on the number of records.
The better alternative from a performance perspective would be to use FetchXML or QueryExpression here.
We might get the below error while using LINQ to query Dataverse – “System.NotSupportedException: ‘Invalid ‘where’ condition. An entity member is invoking an invalid property or method.’” Here we got the below error because we used the HasValue property.
Here the issue with HasValue arises because FetchXML doesn’t have a direct equivalent for nullable checks like HasValue in LINQ. In FetchXML, null checks are handled explicitly through conditions like neq (not equal) or eq (equal) with the null value. Therefore, instead of using HasValue, we need to manually check for null using != null or GetValueOrDefault().
We will also get the same error on below query.
Here we get this error because OriginatingLeadId is a LookUp referencing Lead table, and we are trying to access the Name property of it in the where clause, which cannot be directly translated into FetchXML. To fix it we can perform a join between the Contact and Lead table.
Let us see one more example.
The query, c.Attributes[“firstname”].ToString() is trying to access the firstname attribute and convert it to a string. However, the LINQ provider doesn’t know how to translate.ToString() into a valid FetchXML query.
To fix it we can use GetAttributeValue method.
Or doing the casting
However, we will get the same not supported error if we try to use Attributes Collection.
The error occurs because of the syntax c.Attributes[“firstname”] directly accesses the internal Attributes dictionary of the Entity object. The LINQ provider in Dataverse (Dynamics 365) cannot translate this access pattern into a FetchXML