Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IEnumerable<T> and IQueryable<T> clarification?

After reading this question, I need to clear up some things.

IQueryable<Customer> custs = from c in db.Customers
where c.City == "<City>"
select c;

IEnumerable<Customer> custs = from c in db.Customers
where c.City == "<City>"
select c;

Questions:

1) Is it ok to say that: in the first query the SQLServer is running the whole operation including where clause and returning ONLY the relevant rows - while the second one does SELECT * ... and returns all rows into C# and THEN filters ?

2) What about if I have a collection merely - in memory. ( var lstMyPerson = new List<MyPerson>() )

IQueryable<MyPerson> lst = from c in lstMyPerson 
where c.City == "<City>"
select c;

vs

IEnumerable<MyPerson> custs = from c in lstMyPerson 
where c.City == "<City>"
select c;

what will be the difference in execution now?

like image 762
Royi Namir Avatar asked Jun 21 '12 06:06

Royi Namir


1 Answers

1: No, that is incorrect

Since you're only storing the result into an IEnumerable<Customer>, but still have the exact same expression that produces the result, they will both execute on the server and return only the relevant rows.

You would get the difference in behavior with this:

IEnumerable<Customer> custs = from c in (IEnumerable<Customer>)db.Customers
    where c. City == "<City>"
    select c;

In this case you are forcing the db.Customers collection to be used as IEnumerable<T>, which when enumerated will fetch the entire collection.

Note that this:

IEnumerable<Customer> x = from c in db.Customers
                          where c.City == "<City>"
                          select c;

is not the same as this:

IEnumerable<Customer> x = from c in db.Customers
                          select c;
IEnumerable<Customer> y = x.Where(c => c.City == "<City>");

In the first case, the where clause will be a part of the SQL, in the second it won't. That is why the linked question/answer involves a difference, whereas your code does not.

Also note that only the statements you have written will not in fact execute anything at all on the server, since they will effectively only store a lazy collection. If you go ahead and enumerate those collections, at that point the relevant bits will be executed on the server.

2: List<T> does not implement or have extension methods for IQueryable<T>, nor will the LINQ operators involved return anything compatible with IQueryable<T>

In this case, the first will not compile.

like image 193
Lasse V. Karlsen Avatar answered Nov 09 '22 22:11

Lasse V. Karlsen