user1176058
user1176058

Reputation: 676

Calling Query builder methods on IQueryable<T>

I'm reading Julia Lerman's programming_entity_framework_2nd_edition.

The book says that we can use a LINQ to Entities method on an ObjectQuery. Like this

context.Contacts.Where("it.FirstName='Robert'").Take(10)

Here is an excerpt from the book that says that we can cast IQueryable to ObjectQuery

"You can’t go the other way, though, adding query builder methods to a LINQ method. For instance, context.Contacts.Take(10) returns a System.LINQ.IQueryable. You can use query builder methods only on an ObjectQuery. If you wanted to append a query builder method to this IQueryable, you would first have to cast the LINQ query to an ObjectQuery and then append the method. Casting a LINQ to Entities query to ObjectQuery is possible because ObjectQuery implements IQueryable"

But when I try to execute this query, I get an exception that says "Query builder methods are not supported for LINQ to Entities queries. For more information, see the Entity Framework documentation."

((ObjectQuery<Contact>)context.Contacts.Take(10)).Where("it.FirstName='Robert'")

I'm using EntityFramework Version 4.3.0

What is wrong with my code?

Upvotes: 0

Views: 771

Answers (2)

Gert Arnold
Gert Arnold

Reputation: 109185

Well, nobody's perfect. It's a flaw in the book. The exception message leaves no doubt about it.

Building an EntitySQL query is quite a different operation than building a LINQ query. The former basically consists of building a string and appending it by query builder methods. This requires knowledge about elements that a LINQ query doesn't have, for instance alias names.

Building a LINQ query, on the other hand, is building an expression tree. It's possible to build an expression off of an EntitySQL query, because in that case, the ES query simply returns itself as ConstantExpression.

So if you start with LINQ, it's LINQ all the way.

Upvotes: 1

PeonProgrammer
PeonProgrammer

Reputation: 1535

you can use LINQ operators on constructs built with QueryBuilder methods, like in your example:

context.Contacts.Where("it.FirstName='Robert'").Take(10)

but not the other way.

context.Contacts.Take(10).Where("it.FirstName='Robert'")

****EDIT****

Ok I am removing the MSDN discussion and returning to your textbook's text. On page 221 of your Julia Lerman book, inside the "How can you tell the difference between LINQ methods and QueryBuilder," it explains that LINQ uses lamda expressions and the eSQL string expressions. So in your .Where("it.FirstName='Robert'") this is not a lambda expression so it turns into a Entity SQL String. Your Take(10) is a lambda so it's not returning the type you're expecting.

Upvotes: 1

Related Questions