Search code examples
c#linqdynamics-crmmicrosoft-dynamics

Linq Queryable from OrganizationServiceProxy throws exception when comparing two fields


I've tried to reduce this example to remove the OrganizationServiceProxy/XrmServiceContext, but now I believe the issue is originating there. I'm pulling data from a Dynamics 365 instance using the code generated by CrmSvcUtil.exe from Microsoft. Here is the relevant snippet:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
CrmServiceClient client = new CrmServiceClient(userName, CrmServiceClient.MakeSecureString(password), string.Empty, orgName, isOffice365: true);

using (OrganizationServiceProxy service = client.OrganizationServiceProxy)
{
    XrmServiceContext crm = new XrmServiceContext(service);

    var q = crm.CreateQuery<Account>();

    List<Account> accounts = q.Where(x => x.AccountNumber != x.dynamics_integrationkey).ToList();
}

I get the following exception:

variable 'x' of type '{company-specific}.Account' referenced from scope '', but it is not defined

This is happening on the last line when the Linq is actually executed. It's only when it's created through the Microsoft.Xrm.Sdk.Client.OrganizationServiceContext that I get the error.

Things I've checked:

  • I get the error when comparing any two fields on the same object (not just Account), even when both are the same exact data type.
  • If I replace crm.CreateQuery... with a hand-populated List...AsQueryable() the Linq works fine
  • Most frustratingly, if I work through an intermediary list with List<Account> a = q.ToList(); to rasterize the result set first then this all works fine. It takes much longer to run because I've forfeited any lazy loading, but it works without error.
  • I've looked at other answers related to the referenced from scope '' but not defined Linq error, but they are all about malformed Linq. I know this Linq is well formed because it works fine if I change the underlying Queryable.

Clearly something is different between a List...ToQueryable() and the Microsoft.Xrm.Sdk.Linq.Query<> created by the XrmServiceContext (which inherits CreateQuery from Microsoft.Xrm.Sdk.Client.OrganizationServiceContext), but I don't know what it is.


Solution

  • The query you are trying to build (compare a field value with another field value on the same entity) is not possible in Dynamics.

    The LINQ Provider still uses QueryExpression under the hood, meaning that your LINQ condition will be converted in a ConditionExpression, and that comparison is not possible.

    Similar questions:

    https://social.microsoft.com/Forums/en-US/d1026ed7-56fd-4f54-b382-bac2fc5e46a7/linq-and-queryexpression-compare-entity-fields-in-query?forum=crmdevelopment

    Dynamics QueryExpression - Find entity records where fieldA equals fieldB