In C#, There are two sets of extension methods (such as Where) which works on top of IEnumerable and IQueryable. which of them used for manipulate in-memory objects and which is used for working with database.? Please help
IEnumerable<T>.Where
method extension.which accepts a Func<TSource, bool> predicate
parameter, forcing the filtering to happen in memory. While querying data from the database, IEnumerable
executes select query
on the server-side, loads data in-memory on the client-side and then filters the data. For the IEnumerable<T>
case, it will be LINQ-to-object
, meaning that all objects matching the original query will have to be loaded into memory from the database. IEnumerable
is suitable for querying data from in-memory collections like List, Array and so on.
IQueryable<T>.Where
method extension, which accepts a Expression<Func<TSource, bool>> predicate
parameter. Notice that this is an expression, not a delegate, which allows it to translate the where condition to a database condition.
While querying data from a database, IQueryable
executes a select query
on server-side with all filters. The difference is that IQueryable<T>
is the interface that allows LINQ-to-SQL (LINQ.-to-anything really) to work. So if you further refine your query on an IQueryable<T>
, that query will be executed in the database, if possible. IQueryable
is suitable for querying data from out-memory (like remote database, service) collections.
IEnumerable<T>
exposes the enumerator, which supports a simple iteration over a collection of a specified type. so it's for in-memory objects
IQueryable<T>
provides functionality to evaluate queries against a specific data source wherein the type of data is known. so it's for working with database
The answer of Reza Jenabi says the most important part.
I just want to add that sometimes it's very similar in code and the error may take some time to notice. If you write a method like :
public List<Thing> GetList(Func<Thing, bool> filter)
{
return dbContext.Things.Where(filter).ToList();
}
You're "filter" won't be translated to SQL. All the content of the Things table will be loaded in memory, then only the filter on loaded data will apply. Not noticeable on an almost empty table, but awfully costly on a table with thousands of records.
So take care to always use Expression<Func>
when you want it to be executed on SQL server side :
public List<Thing> GetList(Expression<Func<Thing, bool>> filter)
{
return dbContext.Things.Where(filter).ToList();
}
Knowing that both methods will be called exactly the same way, for example :
Repository.GetList(t => t.IsMyThing || t.WhateverYouWant);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.