Passing Func to Where changes return type from IQueryable to IEnumerable
c#, lambda, linq
Solution
`IQueryable` is using an expression tree to build predicate. So, instead of
Func<MyClass, bool> predicate = x => GetPredicate();
use:
Expression<Func<MyClass, bool>> predicate = x => GetPredicate();
Keep in mind: While using `IQueryable` expression tree is built (tree that represents operation (as operands and arguments) made on collection). In order to translate tree into other form (let's say sql query, depends on LINQ proider) translator must know all operands used in to tree. It looks like that translator in service where you are passing `IQueryable` don't know what does `GetPredicate` function do (and don't know how to translate it to sql query) so throws Not Supported Exception..
The same thing is with Func instead of Expression. Func is complied version of predicate (stored as delegate) - provider don't know how to translate delegates. When Expression is used, the predicate is stored as tree, so provider can "look inside" an expression and translate it correctly.
Problem
I have the following code; ``` IQueryable<MyClass> query = listOfObjects.Where(x => x.SomeProp == 1); ``` I pass this to a method on a particular API that is expecting an IQueryable, which is fine. However, I want to dynamically build up the predicate, so I'm using `Expression.Lambda` to achieve this, and I then `.Compile` it to turn it back into a `Func<MyObject, bool>`. I would have expected that the following would have worked; ``` Func<MyClass, bool> predicate = x => GetPredicate(); IQueryable<MyClass> query = list.Fields.Where(predicate); ``` However, passing `predicate` to `Where` has changed the return type to `IEnumerable<MyClass>`, which isn't the type required by the API obviously. I did (naively) try `predicate.AsQueryable()`, but the API in question (SharePoint Client Object model) just fails with a generic "Specified method is not supported." error message. I don't know if this a limitation of the LINQ provider that is behind the scenes, but regardless... I'm keen to understand why pulling the `Func` out into its own variable and passing it in to `Where` affects the type inference in the way it does.