locked
Linq Query Failing - "'Contact' entity doesn't contain attribute with Name = <entity referennce name>." RRS feed

  • Question

  • Start

    I ran across a linq error today where by a seemling straightforward linq query failed.

    The query in question was on customised entities, however I have recreated the same error using the OTB account and contact entities.

    The query below fails with the error "'Contact' entity doesn't contain attribute with Name = 'parentaccountid'."

                using (var ctx = new OrganizationServiceContext (_serviceProxy))             {                 var accounts = (from a in ctx.CreateQuery<Account>()                            join c in ctx.CreateQuery<Contact>()                                on a.AccountId equals c.AccountId.Id                            where c.BirthDate == null                                 && a.ParentAccountId != null                            select c                     ).ToList();             }

    Interesting enough - this query fails with the error: "'Account' entity doesn't contain attribute with Name = 'birthdate'."

    (I just swapped the order of the parameters in the where clause)

                using (var ctx = new OrganizationServiceContext (_serviceProxy))
                {
                    var accounts = (from a in ctx.CreateQuery<Account>()
                               join c in ctx.CreateQuery<Contact>()
                                   on a.AccountId equals c.AccountId.Id
                               where a.ParentAccountId != null
                                    && c.BirthDate == null
                               select c
                        ).ToList();
                }

    Finally the query works where I only include one of the filters in the where clause - it doesnt matter which one is included.

    This only seems to occur where one of the parameters is an entity reference - if i changed the filter from ParentAccountId to AccountName it works fine.

    As far as I am aware there is no valid reason for this query failing - I would imagine that it would work if I were to manually build the QueryExpression in the old CRM 4 manner - I am wondering if I am missing something obvious?

    Wednesday, February 22, 2012 7:19 PM

Answers

  • Hi Malachy,

    The reason your linq is failing is that when compiled into a query expression, the where clause ends up being a filter on the linkentity from account to contact, but the contact entity doesn't have parentaccountid.

    This is what the query expression looks like when compiled:

    <QueryExpression xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
      <ColumnSet>
        <AllColumns>true</AllColumns>
        <Columns xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
      </ColumnSet>
      <Criteria>
        <Conditions />
        <FilterOperator>And</FilterOperator>
        <Filters />
      </Criteria>
      <Distinct>false</Distinct>
      <EntityName>account</EntityName>
      <LinkEntities>
        <LinkEntity>
          <Columns>
            <AllColumns>true</AllColumns>
            <Columns xmlns:d5p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
          </Columns>
          <EntityAlias>c_0</EntityAlias>
          <JoinOperator>Inner</JoinOperator>
          <LinkCriteria>
            <Conditions />
            <FilterOperator>And</FilterOperator>
            <Filters>
              <FilterExpression>
                <Conditions>
                  <ConditionExpression>
                    <AttributeName>birthdate</AttributeName>
                    <Operator>Null</Operator>
                    <Values xmlns:d9p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
                  </ConditionExpression>
                  <ConditionExpression>
                    <AttributeName>parentaccountid</AttributeName>
                    <Operator>NotNull</Operator>
                    <Values xmlns:d9p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
                  </ConditionExpression>
                </Conditions>
                <FilterOperator>And</FilterOperator>
                <Filters />
              </FilterExpression>
            </Filters>
          </LinkCriteria>
          <LinkEntities />
          <LinkFromAttributeName>accountid</LinkFromAttributeName>
          <LinkFromEntityName>account</LinkFromEntityName>
          <LinkToAttributeName>accountid</LinkToAttributeName>
          <LinkToEntityName>contact</LinkToEntityName>
        </LinkEntity>
      </LinkEntities>
      <Orders />
      <PageInfo>
        <Count>0</Count>
        <PageNumber>1</PageNumber>
        <PagingCookie i:nil="true" />
        <ReturnTotalRecordCount>false</ReturnTotalRecordCount>
      </PageInfo>
      <NoLock>false</NoLock>
    </QueryExpression>

    You can see that the filter for parentaccountid is in the wrong place - hence the error.

    To fix, luckily it's quite simple. You need:

    using (var ctx = new OrganizationServiceContext (_serviceProxy))
                {
                    var accounts = (from a in ctx.CreateQuery<Account>()
                               join c in ctx.CreateQuery<Contact>()
                                   on a.AccountId equals c.AccountId.Id
                               where c.BirthDate == null
                               where a.ParentAccountId != null
                               select c
                        ).ToList();
                }

    Notice that there are two where clauses - which reflects the fact that there needs to be two separate filters - one on the main entity and one on the link entity in the Query Expression.

    hth,

    Scott


    Scott Durow
    Read my blog: www.develop1.net/public
    If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"

    Wednesday, February 22, 2012 9:09 PM
    Answerer

All replies

  • Hi Malachy,

    The reason your linq is failing is that when compiled into a query expression, the where clause ends up being a filter on the linkentity from account to contact, but the contact entity doesn't have parentaccountid.

    This is what the query expression looks like when compiled:

    <QueryExpression xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
      <ColumnSet>
        <AllColumns>true</AllColumns>
        <Columns xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
      </ColumnSet>
      <Criteria>
        <Conditions />
        <FilterOperator>And</FilterOperator>
        <Filters />
      </Criteria>
      <Distinct>false</Distinct>
      <EntityName>account</EntityName>
      <LinkEntities>
        <LinkEntity>
          <Columns>
            <AllColumns>true</AllColumns>
            <Columns xmlns:d5p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
          </Columns>
          <EntityAlias>c_0</EntityAlias>
          <JoinOperator>Inner</JoinOperator>
          <LinkCriteria>
            <Conditions />
            <FilterOperator>And</FilterOperator>
            <Filters>
              <FilterExpression>
                <Conditions>
                  <ConditionExpression>
                    <AttributeName>birthdate</AttributeName>
                    <Operator>Null</Operator>
                    <Values xmlns:d9p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
                  </ConditionExpression>
                  <ConditionExpression>
                    <AttributeName>parentaccountid</AttributeName>
                    <Operator>NotNull</Operator>
                    <Values xmlns:d9p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
                  </ConditionExpression>
                </Conditions>
                <FilterOperator>And</FilterOperator>
                <Filters />
              </FilterExpression>
            </Filters>
          </LinkCriteria>
          <LinkEntities />
          <LinkFromAttributeName>accountid</LinkFromAttributeName>
          <LinkFromEntityName>account</LinkFromEntityName>
          <LinkToAttributeName>accountid</LinkToAttributeName>
          <LinkToEntityName>contact</LinkToEntityName>
        </LinkEntity>
      </LinkEntities>
      <Orders />
      <PageInfo>
        <Count>0</Count>
        <PageNumber>1</PageNumber>
        <PagingCookie i:nil="true" />
        <ReturnTotalRecordCount>false</ReturnTotalRecordCount>
      </PageInfo>
      <NoLock>false</NoLock>
    </QueryExpression>

    You can see that the filter for parentaccountid is in the wrong place - hence the error.

    To fix, luckily it's quite simple. You need:

    using (var ctx = new OrganizationServiceContext (_serviceProxy))
                {
                    var accounts = (from a in ctx.CreateQuery<Account>()
                               join c in ctx.CreateQuery<Contact>()
                                   on a.AccountId equals c.AccountId.Id
                               where c.BirthDate == null
                               where a.ParentAccountId != null
                               select c
                        ).ToList();
                }

    Notice that there are two where clauses - which reflects the fact that there needs to be two separate filters - one on the main entity and one on the link entity in the Query Expression.

    hth,

    Scott


    Scott Durow
    Read my blog: www.develop1.net/public
    If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"

    Wednesday, February 22, 2012 9:09 PM
    Answerer
  • Thanks for that Scott, really appreciate it,  Just out of interest how did inspect the compiled query?
    Wednesday, February 22, 2012 10:39 PM
  • Hi Malachy,

    I used my Linq to FetchXml converter sample:

    http://code.msdn.microsoft.com/Convert-CRM2011-Linq-into-93a163ee

    But you could also use LinqPad.

    hth,

    Scott


    Scott Durow
    Read my blog: www.develop1.net/public
    If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"

    Thursday, February 23, 2012 8:44 AM
    Answerer
  • where c.BirthDate == null OR where a.ParentAccountId != null

    how can I do something like this in (OR) logic not (AND)...it gives me Invalid expression term 'where'

    Wednesday, November 28, 2012 6:04 PM
  • Thanks a lot!
    Thursday, June 25, 2015 8:09 AM