Answered by:
Linq Query Failing - "'Contact' entity doesn't contain attribute with Name = <entity referennce name>."

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"- Proposed as answer by Scott Durow (MVP)MVP, Editor Wednesday, February 22, 2012 9:09 PM
- Marked as answer by Malachy O Connor Wednesday, February 22, 2012 10:37 PM
Wednesday, February 22, 2012 9:09 PMAnswerer
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"- Proposed as answer by Scott Durow (MVP)MVP, Editor Wednesday, February 22, 2012 9:09 PM
- Marked as answer by Malachy O Connor Wednesday, February 22, 2012 10:37 PM
Wednesday, February 22, 2012 9:09 PMAnswerer -
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 AMAnswerer -
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