Why can't we call Standard Query Operators on a sequence of type IQueryable<T>? - linq

Standard Query Operators operate on Linq to Object sequences, which implement IEnumerable<T> interface, while Linq to Sql operators are called on sequences of type IQueryable<T> interface. Thus Standard Query Operators cannot get called on a sequence of type IQueryable<T> unless this sequence is first cast to IEnumerable<T> ( via AsEnumerable operator )
a) Why can't Standard Query Operators that don't have Linq to Sql counterparts ( like Reverse() ), be called on a IQueryable<T> sequence? Namely, IQueryable<T> derives from IEnumerable<T> and thus an extension method which extends classes implementing IEnumerable<T> should also extend classes implementing interfaces derived from IEnumerable<T> ?!
b) Anyways, why would it be a bad idea to be able to call Standard Query Operators ( those that don't have Linq to Sql counterparts ) on a sequence of type IQueryable<T>, without first casting this sequence to IEnumerable<T> ( via AsEnumerable operator )?
thanx

IQueryable<T> in general is not just for Linq to SQL, it's a convention that any query provider may choose to support with a limited set of operations - not all query providers support the same subset.
The subset that is supported depends on what makes sense in the domain of the query provider. IQueryable<T> operates on an expression tree that allows the query provider to translate the query into a domain specific language for the underlying data source (i.e. SQL).

If I correctly understood your question Linq to SQL query produces the SQL query because linq to SQL is different Linq provider, IEnumerable used for query in memory collections

Related

What is the difference between an IQueryable's Contains() and an IEnumerable's Contains()?

I have an IQueryable custs, a Customer cust, a CustomerComparer custCp which implements IEqualityComparer.
When I call custs.Contains(cust, custCp) I get an exception:
System.NotSupportedException: Unsupported overload used for query operator 'Contains'
But when I call custs.AsEnumerable().Contains(cust,custCp) it works. Can anyone explain why?
An operation on an IQueryable (in the case of Linq to Entities) is translated to SQL and executed in the database. Since you have an IEqualityComparer written in C#, the comparer can't be translated to SQL and the overload can't be supported.
When you translate it to an IEnumerable using AsEnumerable(), all the data is transferred from the database to memory, where the overload can be easily supported. The downside of course being that you're transferring more data than necessary (potentially the whole table) to have it filtered in memory.
IQueryable is implemented by query providers and under the hood translated into something the target system can understand. For example, IQueryable.Contains might be translated to a x IN y SQL expression.
On the other hand, IEnumerable is not translated like that. Its Contains works on anything that implements IEnumerable properly.
Using the IQueryable operators are executed server-side and therefore will gain you some performance as the query is executed remotely, whereas IEnumerable is executed locally (client-side). This means that if you were to get a database table, convert it to enumerable and then apply Contains on it, the whole table needs to be downloaded to your computer to be enumerated.

Why using Count with IQueryable is considered unfeasible

If I have the following code:-
IQueryable<People> list = repository.FindAllPeople;
int count = list.Count();
Then is it considered as unfeasible to count IQueryable objects and it is better to use IEnumerable?
BR
You have been misinformed.
IEnumerable will use Linq to objects, all methods are executed on objects in memory. - IQueryable will use whatever implementation of the Linq extension methods is provided by the specific provider. In this case (a repository) I would guess it is most likely a provider that maps the Linq expressions to database statements.
That means if you use IQueryable:
IQueryable<People> list = repository.FindAllPeople;
int count = list.Count();
The count is determined on the database itself, i.e. as a query "select count(*) from People". This is usually very, very fast.
If you use IEnumerable:
IEnumerable<People> list = repository.FindAllPeople;
int count = list.Count();
All People instances will be materialized to memory one by one while Linq to objects is iterating through the collection to determine the count. This will be very slow and should be avoided whenever possible.
Since not all method calls can be mapped to database queries it is sometimes unavoidable to use an IEnumerable, but all filtering, joining and grouping should be done on an IQueryable if possible, then as a last step you can use the AsEnumerable() extension methods to switch to using IEnumerable and Linq to objects.
I'm not familiar with the infeasability of IQueryable, but this blog post seems to indicate that IQueryable is much more preferable to IEnumerable because IQueryable allows access to the underlying expression.
This may only be relevant in the case of a Where clause and not impact .Count().

Determine provider of IQueryble(Object)

Is it possible to determine if an IQueryable<Object> is a LINQ-to-sql object or not? (Has a SQL statement as its source)
Yes, a DataContext returns System.Data.Linq.Table<T>s (IQueryable<T>) or System.Data.Linq.ITables (IQueryable), so you can test whether your IQueryable instance is one of these.
Edit:
When a Linq operation (like Select, or OrderBy) is applied to the IQuerable the result is a System.Data.Linq.DataQuery. This is an internal type, so you cannot use the is operator. In stead, do y.GetType().FullName.StartsWith("System.Data.Linq.DataQuery`1").

Linq, what is difference in returning data in var, list, IEnumerable and IQueryable?

I am new to Linq please guide me on some basic things.
In read some articles on Linq. Some authers fill data in var from Linq query, some fills list of custom type objects and some fills data in IEnumerable and some do it in IQuryable. I could not get what is difference in these 4 and which one should be used in which situation.
I want to use Linq to SQL. What should I use?
Well, you can never declare that a method returns var - it's only valid for local variables. It basically means "compiler, please infer the static type of this variable based on the expression on the right hand side of the assignment operator".
Usually a LINQ to Objects query will return an IEnumerable<T> if it's returning a sequence of some kind, or just a single instance for things like First().
A LINQ to SQL or EF query will use IQueryable<T> if they want further query options to be able to build on the existing query, with the added bits being analyzed as part of the SQL building process. Alternatively, using IEnumerable<T> means any further processing is carried out client-side.
Rather than focusing on what return type to use, I suggest you read up on the core concepts of LINQ (and the language enhancements themselves, like var) - that way you'll get a better feel for why these options exist, and what their different use cases are.

Linq to Nibernate design

I thought that the purpose of using Linq2Nibernate was to return IQueryable and build up an expression tree. I am not sure if this is correct or not.
Why would anyone use Linq2Nibernate if they are not going to return IQueryable?
What else would it be used for?
I would love some more input on this topic
Linq For Nhibernate
I'm planning to use NHibernate.Linq to replace my HQL and criteria API queries with LINQ expressions. In other words, I'll generate the query in code (as a LINQ expression) and then pass it to NHibernate.Linq and NHib to convert it into a database query.
FYI there is an alpha version available.
I have planed to start using Linq2Nibernate but haven't got round to i yet.
My reason for wanting to user Linq2Nibernate is the nice syntax when constructing criterions and later querying them out.
Here is a nice simple example.
http://ayende.com/Blog/archive/2007/03/16/Linq-for-NHibernate.aspx
I am using Linq2Nhibernate with my repository pattern that returns IQueryable objects.
As you know, IQueryable is only a query definition - doesn't touch database yet.
Then local requirements are added to the query and finally the object or list is materialized.
Seems to work excellent and prevents unnecessary db queries for partial data at higher abstract layers.
What's Linq2NHibernate? As there are several projects which tried to implement a linq provider for nhibernate but all stopped before reaching completion.
Any linq provider needs to return IQueryable, or better an IEnumerable as that's how linq works. It's convenient to return an IQueryable as you then can re-use existing code to pad additional operators to an already created query (as ctx.Employee which might return IQueryable is already a query)

Resources