Invalid CRM 2011 LINQ Query: "Invalid 'where' condition. An entity member is invoking an invalid property or method."
Solution 1
Because the Audit entity doesn't provide an ground-level attribute for the logical name/type code of the entity a particular record is related to, the best you can do here is to link to the entity (or entities) you wish to locate audit records for -- that is without retrieving all the records.
A general technique for scenarios like this is that you can link to an related entity with a semi-nonsense condition like checking that the primary key is not null. For your case, just the link should be enough.
An example for pulling audit records tied to a contact:
from a in OrgContext.CreateQuery<Audit>()
join c in ContactSet on a.ObjectId.Id equals c.ContactId
where a.ObjectId != null && a.CreatedOn > since
select a
Solution 2
Add a ToList()
after the CreateQuery
method, in this way your conditions will work with LINQ to Objects
provider and not with the CRM LINQ provider (and its limitations)
public List<Audit> GetAuditChangesSince(DateTime since, string entityType)
{
return (from a in OrgContext.CreateQuery<Audit>().ToList()
where
a.ObjectId != null && a.ObjectId.LogicalName == entityType &&
a.CreatedOn > since
select a).ToList();
}
Ryan
Working in Investment Banking, developing applications and managing small to mid-sized development teams, across different regions. I have worked on a large range of projects: web based tools, feeds, CRM and proprietary platforms. I'm really keen to do development and management 'the right way' and try to stay up-to-date with the latest developments (particularly in the .NET world) Technologies I use include C#, ASP.NET (+DevX Controls, which are awesome), Java, Sybase, Oracle, SQL Server, VBA (show me a developer in a bank that hasn't got thier hands dirty on VBA). Especially keen in using C# - it seems to be an incredibly expressive language. I consider myself lucky... I love my job! #SOreadytohelp
Updated on June 21, 2022Comments
-
Ryan almost 2 years
I am trying to execute this query to retrieve Audit items for specific entity types
public List<Audit> GetAuditChangesSince(DateTime since, string entityType) { return (from a in OrgContext.CreateQuery<Audit>() where a.ObjectId != null && a.ObjectId.LogicalName == entityType && a.CreatedOn > since select a).ToList(); }
The a.ObjectId != null && a.ObjectId.LogicalName == entityType && clause is causing problems. I know .Equals() may cause problems (hence ==) and there are these limitations to the LINQ Provider:
The left side of the clause must be an attribute name and the right side of the clause must be a value
The left side is a property and the right side is a constant. Is the .ObjectId.LogicalName causing the problem?
-
Ryan almost 11 yearsWould that cause the OrgContext.CreateQuery<Audit>() to evaluate, therefore pulling all Audit records from the server, before applying filtering?
-
Guido Preite almost 11 yearsWith high probability is yes, you can split in two steps, retrieving first the Audit with only the createdon condition and after evaluate the entity type.
-
ccellar almost 11 years@Ryan yes, it will evaluate.
-
GotDibbs almost 11 yearsDepending on the level of auditing in the org, splitting the query this way is a really bad idea. You'll be pulling back an excessive number of records.
-
Ryan almost 11 yearsThanks for your answer. Could you kindly explain what you mean by "ground-level attribute"? Thank you.
-
GotDibbs almost 11 yearsNo problem! I just meant that, as you suggested in your question, since there is no actual attribute on the audit entity for the logical name/type code of the entity the audit record is related to, there is no way to filter directly on the audit entity. In terms of querying CRM we have to think of fields of type
EntityReference
as only being queryable by theirId
properties. The metadata of what type of record is associated to that Id is abstracted away from us and not directly queryable in this instance. Let me know if I can clarify further!