Here is a simple explanation:
IEnumerable<User> usersEnumerable = db.UserSet; IQueryable<User> usersQueryable = db.UserSet; var users = ; var age32StartsWithG = users.Where(user => user.Age == 32) .Where(user => user.Name.StartsWith("G");
If you use usersEnumerable , when you start listing it, two Where will be executed sequentially; First, the ObjectSet will retrieve all the objects, and the objects will be filtered to those aged 32, and then they will be filtered to those whose name begins with G.
If you use usersQueryable , the two Where will return new objects that will accumulate the selection criteria, and when you start listing it, it will translate all the criteria into the query. This makes a noticeable difference.
You usually donβt need to worry, since you will tell var users or ObjectSet users when you declare your variable, which means that C # will know that you are interested in calling the most specific method that is available on ObjectSet , and the query operator methods are IQueryable ( Where , Select , ...) are more specific than IEnumerable methods. However, if you pass objects to methods that take IEnumerable parameters, they may call the wrong methods.
You can also use a method that works to your advantage, using the AsEnumerable() and AsQueryable() methods to start using a different approach. For example, var groupedPeople = users.Where(user => user.Age > 15).AsEnumerable().GroupBy(user => user.Age); will delete the right users with the database query, and then group the objects locally.
As others have said, it's worth repeating that nothing happens until you start listing the sequences (using foreach ). Now you need to understand why this could not be otherwise: if all the results were obtained immediately, you could not create queries to translate into a more efficient query (for example, an SQL query).
Jesper
source share