Distinguish between IEnumerable<T> and IQueryable<T>

Distinguish between IEnumerable<T> and IQueryable<T>

The LINQ query method provides a total of two extension methods. Under the System.Linq namespace, there are two static classes: the Enumerable class, which extends the collection that inherits the IEnumerable<T> interface; the Queryable class, which inherits the IQueryable< The collection of T> interfaces is expanded. We will find that the interface IQueryable<T> actually inherits the IEnumerable<T> interface. In this case, why did Microsoft design two sets of extension methods?

From the LINQ query function, we know that it can actually be divided into three categories: LINQ to OBJECTS, LINQ to SQL and LINQ to XML. In fact, the two sets of micro-design interfaces are mainly for LINQ to OBJECTS and LINQ to SQL, and the internal processing mechanism of the two queries is completely different. For LINQ to OBJECTS, use the extension method in Enumerable to sort and query the local collection. The query parameter accepts Func<>, Func<> is called a predicate expression, which is equivalent to a delegate. For LINQ to SQL, use the extension method in Queryable, which accepts Expression<>.

So, when to use IQueryable<T> and when to use IEnumerable<T>?

1. let's take a look at the LINQ to SQL code:

using (var context = new NorthwindEntities()) {var orderTmp = context.Orders.Where(p=>p.CustomerID=="RATTC"); var orders = orderTmp.Where(p => p.OrderDate> new DateTime( 1997, 1, 1)); foreach (var order in orders) {Console.WriteLine("OrderId:" + order.OrderID);}}

Through vs Intellisense, we can see that the return type of Where is IQueryable, and the parameter is of type Expression:

Let's look at this piece of code again:

using (var context = new NorthwindEntities()) {var orderTmp = context.Orders.Where(p => p.CustomerID == "RATTC").AsEnumerable(); var orders = orderTmp.Where(p => p.OrderDate > new DateTime(1997, 1, 1)); foreach (var order in orders) {Console.WriteLine("OrderId:" + order.OrderID);}}

The difference in this code is that we return the LINQ query to the IEnumerable type. Let's take a look at the effect of vs. Intellisense:

Since we added AsEnumerable() in the LINQ query, we can see in the second statement that the return type has become IEnumerable, and the parameter has also become Func<> type.

As for the difference between these two pieces of code, we execute the code separately and look at the generated sql statement in the sql profiler:

The first code effect:

Although we used two statements to query, but in the end only one SQL statement was generated, which merged the query parameters.

The second code effect:

This time we still only see one SQL statement, but there is only one query condition, but the results of the two queries are the same.

The reason is that Func<> will be directly compiled into IL code by the compiler, but Expression<> just stores an expression tree for processing at runtime, LINQ to SQL will eventually convert the expression tree into the corresponding SQL statement, and then Execute in the database.

Now we should know when to use IEnumerable<T> and when to use Iqueryable<T>.

Reference:https://cloud.tencent.com/developer/article/1503526 IEnumerable