I use ((ObjectQuery)IQueryable).ToTraceString() to obtain and tweak SQL code that is going to be executed by LINQ.
My problem is that unlike most IQueryable methods IQueryable.Count as defined like this:
public static int Count(this IQueryable source) {
return (int)source.Provider.Execute(
Expression.Call(
typeof(Queryable), "Count",
new Type[] { source.ElementType }, source.Expression));
}
executes query without compiling and returning IQueryable.
I wanted to do the trick by something like this:
public static IQueryable CountCompile(this IQueryable source) {
return source.Provider.CreateQuery(
Expression.Call(
typeof(Queryable), "Count",
new Type[] { source.ElementType }, source.Expression));
}
But then CreateQuery gives me the following exception:
LINQ to Entities query expressions can only be constructed from instances that implement the IQueryable interface.
Here’s an actual working answer I came up with when I tried to so the same. The exception says “can only be constructed from instances that implement the IQueryable interface”, so the answer seems simple: return a queryable something. Is that possible when returning a
.Count()? Yes!To use it:
Basically, what this does is wrap a non-IQueryable query in a subselect. It transforms the query into
except lets the context’s QueryProvider handle the query. The generated SQL is pretty much what you should expect: