I have the following compiled query.
private static Func<Db, int, IQueryable<Item>> func =
CompiledQuery.Compile((Db db, int id) =>
from i in db.Items
where i.ID == id
select i
);
This executes on the database immediately when I do
var db = new Db()
var query = func(db, 5); // Query hits the database here
As in before doing
var result = query.SingleOrDefault(); // Happens in memory
But if this query wasn’t compiled, as in
var query = from i in db.Items
where i.ID == id
select i
then it executes on the database after doing
var result = query.SingleOrDefault();
Is this the expected behaviour?
Note: This is a duplicate of When does a compiled query that returns an IQueryable execute?, but all the answers on there seem to disagree with my findings. I have posted my answer there, but I don’t know how to get peoples’ attention to it as it’s over 2 years old.
Interesting question. Taking it to decompiled sources, when you compile a query, this is what happens:
The UseExpressionCompile method is defined like this:
This evaluates to false for the expression you’ve defined, so the else case is used.
The Invoke is like this:
The ExecuteQuery is like:
In this case our provider is the SqlProvider class, the SqlProvider.CompiledQuery is the class that implements ICompiledQuery. Execute on that class is implemented:
SqlProvider.ExecuteAll calls SqlProvider.Execute, which is a pretty big method, so I’ll post the highlights:
In between acquiring and releasing the connection it exceutes sql commands. So I’d say you’re right. Contrary to popular belief, compiled queries don’t behave the same as uncompiled queries when it comes to deferred execution.
I’m pretty sure you can download the actual source code from MS, but I don’t have it handy and Resharper 6 has an awesome go to decompiled function, so I just used that.