Why are Func <> and the expression <Func <>> interchangeable? Why does one work in my case?

I have a data access class that took some time to work. For my application, I need to get different types of SQL Server tables, where the WHERE clause differs only in the column name: some columns are read_time, others are ReadTime, and others are LastModifiedTime. So I thought I would go into the WHERE clause, so I did not need to create a new method for 50 different tables. It looks simple and it works, but I don’t understand anything.

This method, with the expression <> as a parameter, works:

 internal List<T> GetObjectsGreaterThanReadTime<T>(Expression<Func<T, bool>> whereClause) where T : class { Table<T> table = this.Database.GetTable<T>(); IEnumerable<T> objects = table.Where(whereClause); return objects.ToList(); } 

Now I tried it like this (below) for a while, and it just hangs on the last line (ToList ()). First, why compile it? I mean, why can expression and Func be used as a parameter interchangeably? Then, why does the expression work and the Func version just hangs?

Note. The only difference between the above and this method is the parameter of the method (expression against Func).

 internal List<T> GetObjectsGreaterThanReadTime<T>(Func<T, bool> whereClause) where T : class { Table<T> table = this.Database.GetTable<T>(); IEnumerable<T> objects = table.Where(whereClause); return objects.ToList(); } 
+6
source share
1 answer

In the version of Expression, Queryable.Where is called, which generates an expression tree, which (when enumerating ToList ) is translated into sql and executed on the database server. Presumably, the database server will use an index based on filter criteria to not read the entire table.

The Func version calls Enumerable.Where , which (when listing ToList ) loads the entire table (which you perceive as a hang), and then runs the filter criteria against objects in memory.

+12
source

Source: https://habr.com/ru/post/912424/


All Articles