db.Courses
is an IQueryable
. While the syntax is virtually identical to the LINQ methods of IEnumerable
, under the hood they're completely different.
The IQueryable
code isn't actually exectued anywhere at all. It just creates a bunch of Expression
objects that different query providers are able to use to do...whatever they want (in this case query a database). Those query providers need to specifically have code to handle any given type of input. There are some things that they either can't sensibly transform into a SQL query, or things that the programmers simply didn't think of or choose to handle (even if it might have a sensible SQL translation).
In sort, the query provider just doesn't know how to translate model.Tracks.Any(t => t.Certification.ID == certificate)
into SQL.
You simply need to know what types of code is and isn't supported by the query provider that you're using and try to manipulate the code you have into something that it can handle. Something like this should work:
var certificates = model.Tracks.Select(t => t.Certification.ID).ToList();
model.Courses = db.Courses
.Where(c => certificates.Contains(c))
.ToList();
If this were C# code executing all of this in LINQ to objects the two queries would be identical, but to a query provider they're not. They simply have special support for knowing when they see List.Contains
to map it to a SQL IN
clause. They didn't add specific support for what you did in your first query.
model.Tracks
? – Sergey Berezovskiy Jun 12 '13 at 16:21c
in the.Where(c => ...
clause. Iscertificate
supposed to bec.certificate
? – klugerama Jun 12 '13 at 16:22IEnumerable<Tracks>
. – shruggernaut Jun 12 '13 at 16:22