Passing in an Expression to a Linq query behaves differently depending on syntax used, and I wonder why this is the case.
Let’s say I have this very generic function
private IEnumerable<Company>
GetCompanies(Expression<Func<Company, bool>> whereClause)
The following implementation works as expected
private IEnumerable<Company>
GetCompanies(Expression<Func<Company, bool>> whereClause)
{
return (from c in _ctx.Companies.Where(whereClause) select c);
}
But this next implementation does not compile
(Delegate ‘System.Func’ does not take 1 arguments)
private IEnumerable<Company>
GetCompanies(Expression<Func<Company, bool>> whereClause)
{
return (from c in _ctx.Companies where whereClause select c);
}
Obviously I can just use the first syntax, but I was just wondering why the compiler does not treat the where keyword the same as the Where extension?
Thanks,
Thomas
The syntax for a query expression involving a
whereclause is (simplifying the complete grammar)whereClauseis not a boolean expression. To recitify this, you have to sayNote that if
whereClausewere aFunc<Company, bool>you could get away withNote that
is translated mechanically by the compiler into
I say mechanically because it performs this translation without doing any semantic analysis to check validity of the method calls etc. That stage comes later after all query expressions have been translated to LINQ method-invocation expressions.
In particular,
is translated to
which is clearly nonsensical.
The reason that
is legit is because
IEnumerable<Company>.Wherehas an overload accepting aFunc<Company, bool>and there is an implicit conversion from anExpression<Func<Company, bool>>to aFunc<Company, bool>.