Search code examples
c#dynamics-crmmicrosoft-dynamics

Dynamics CE entity does not contain attribute with name using ServiceClient while entity has attribute and can be queried using Web API


I have faced an issue when retrieving entities from Dynamics CE based on a QueryExpression using the ServiceClient class and doing so for a specific entity by a specific field.

My code is built to use the field _invoiceid_value to retrieve an Invoice Product (logical name Invoice Detail) by the reference it has to an invoice.

It looks as follows:

public async Task<IEnumerable<InvoiceDetail>> GetInvoiceDetailsByInvoiceIdAsync(Guid invoiceId)
{
    var query = new QueryExpression(InvoiceDetail.EntityLogicalName);
    query.ColumnSet = new ColumnSet(true);
    query.Criteria.AddCondition("_invoiceid_value", ConditionOperator.Equal, invoiceId);

    return await _repository.GetInvoiceDetailsByQueryAsync(query);
}

The repository class only handles the ServiceClient and holds no logic. When the ServiceClient sends this request I get the following error message:

System.Private.ServiceModel: 'InvoiceDetail' entity doesn't contain attribute with Name = '_invoiceid_value' and NameMapping = 'Logical'.
MetadataCacheDetails: ProviderType=Dynamic,
StandardCache=True,
IsLoadedInStagedContext = False,
Timestamp=170102496,
MinActiveRowVersion=170102496,
MetadataInstanceId=19121005,
LastUpdated=2024-02-11 09:54:52.403,
OrgId=.

This I read as the response is that the field _invoiceid_value does not exist for the entity Invoice Detail. The problem is that it very much does exist, both when looking at the entity in Dynamics CE using Level up for Dynamics 365 but also when using their Web API.

I tried this making the following request to their API where the organisation and invoiceid values contain correct values:

https://organisation.api.crm4.dynamics.com/api/data/v9.2/invoicedetails?$filter=_invoiceid_value eq invoiceid

This returns a 200 OK with the requested Invoice Detail entity.

Why does this work using the Dynamics CE Web API but not when I am using the ServiceClient class in combination with a QueryExpression?

The ServiceClient class also support OData queries to the Web API and that works too, so the issue only exists when using the QueryExpression. I have used the QueryExpresssion approach for the last two years without any issues.

My main expertise is not in Dynamics, so it could be that I am missing something obvious from that component. But considering it works with an OData query I cannot see why it would not work using a QueryExpression.


Solution

  • When working with the IOrganizationService interface (implemented by ServiceClient) entity and attribute names must be specified by their logical names.

    Thus the condition

    query.Criteria.AddCondition("_invoiceid_value", ConditionOperator.Equal, invoiceId);
    

    should be written like this:

    query.Criteria.AddCondition("invoiceid", ConditionOperator.Equal, invoiceId);
    

    (_invoiceid_value is an OData syntax)