简体   繁体   中英

C# extension methods types

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM