Before anyone votes to close this as a duplicate of this, this and many other similar questions, please read the question carefully as I don't think it is (even though it looks very similar).
I have a Linq query as follows...
List<int> ids = ctx
.Where(a => a.PartInformationTypeID == pitID && vals.Contains(a.PartDefinitionID))
.Select(a => a.SystemID)
.Distinct()
.ToList();
...where pitID
is an int
and vals
is a List<int>
This works fine, but as I have four such queries, only differing by the lambda in the Where
clause, I thought it would be better to pull the code out into a common method...
private List<int> DoAdvancedSearch(Func<MyType, bool> p)
{
return ctx
.Where(a => p(a))
.Select(a => a.SystemID)
.Distinct()
.ToList();
}
I could then call this as follows...
List<int> ids = DoAdvancedSearch(systemIDs,
a => a.PartInformationTypeID == pitID && vals.Contains(a.PartDefinitionID))
However, this method gives a run-time exception "System.NotSupportedException: 'The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.'"
Having read loads of other questions with the same exception, I managed to solve it by changing the method as follows...
private List<int> DoAdvancedSearch(Expression<Func<MyType, bool>> p)
{
return ctx
.Where(p)
.Select(a => a.SystemID)
.Distinct()
.ToList();
}
However, one thing I can't seem to find is why my first query above (with the lambda in the Where
clause) didn't work, wheras the second query in the extracted method did? I don't think it's an issue with the actual lambda, as it doesn't contain anything that EF can't translate into SQL (which it demonstrably does with the first version), so it's evidently something to do with the fact that the lambda was passed as a Func
rather than an Expression
.
The closest I found to an explanation was in the answer to this question, but that was based around the fact that the code being passed in couldn't be translated into SQL. As I said, I don't think that's the problem here, as EF managed to translate it fine in the first code snippet.
Anyone able to explain why my example doesn't work with a Func
?
As a secondary question, anyone able to explain why .Where(a => p(a))
gave a compiler error of "Method name expected" on p
, but was fine with .Where(p)
? I thought these were equivalent.
Thanks