"The presence of certain operations, such as Enumerable.Contains, in a LINQ to Entities query can result in the translation of the query to be dependent on an argument passed to the query. For instance, a query like this:
from e in context.Employees
where sectionList.Contains(e.SectionId)
select e;
… would produce different translations depending on the contents of the sectionList. E.g. if sectionList = new[] {1,2,3}, the translation would be similar to this:
SELECT *
FROM Employees AS e
WHERE e.SectionId IN (1,2,3);
But if sectionList = new[] {4,5,6,7}, the translation would be similar to this:
SELECT *
FROM Employees AS e
WHERE e.SectionId IN (4,5,6,7);
When a regular query includes such an operator and the argument is included in the query (e.g. as a constant expression that points to a field of the closure or as a an array initialization expression embedded in the query), LINQ to Entities can simply encode the data into the CQT translation and later into the target query.
However, parameterizing such data argument in CompiledQuery is not supported because there is no single translation that would work with all possible variations of the argument.
Currently we also disable caching such query in auto-compiled queries. But given that during the LINQ translation phase the collection argument of Enumerable.Contains gets encoded into nodes of the CQT and that the new auto-compiled query feature uses a string representation of the CQT as the key into the cache entries, auto-compiled queries can cache these queries. "
This item was migrated from the DevDiv work item tracking system [ID=221608].
Comments: Note for triage: we discussed trying to implement auto-compiled query improvements in the next release.
from e in context.Employees
where sectionList.Contains(e.SectionId)
select e;
… would produce different translations depending on the contents of the sectionList. E.g. if sectionList = new[] {1,2,3}, the translation would be similar to this:
SELECT *
FROM Employees AS e
WHERE e.SectionId IN (1,2,3);
But if sectionList = new[] {4,5,6,7}, the translation would be similar to this:
SELECT *
FROM Employees AS e
WHERE e.SectionId IN (4,5,6,7);
When a regular query includes such an operator and the argument is included in the query (e.g. as a constant expression that points to a field of the closure or as a an array initialization expression embedded in the query), LINQ to Entities can simply encode the data into the CQT translation and later into the target query.
However, parameterizing such data argument in CompiledQuery is not supported because there is no single translation that would work with all possible variations of the argument.
Currently we also disable caching such query in auto-compiled queries. But given that during the LINQ translation phase the collection argument of Enumerable.Contains gets encoded into nodes of the CQT and that the new auto-compiled query feature uses a string representation of the CQT as the key into the cache entries, auto-compiled queries can cache these queries. "
This item was migrated from the DevDiv work item tracking system [ID=221608].
Comments: Note for triage: we discussed trying to implement auto-compiled query improvements in the next release.