Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are Func<> and Expression<Func<>> Interchangeable? Why does one work in my case?

I have a data access class that took me a while to get working. For my app, I need to get different types of SQL Server tables where the WHERE clause only differs by the column name: some columns are read_time, others are ReadTime, and others are LastModifiedTime. So I thought I'd pass in the WHERE clause so I didn't need to create a new method for 50 different tables. It looks simple, and it works, but I don't understand something.

This method, with Expression<> as the 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 was trying it this way (below) for a while, and it would just hang on the last line (ToList()). First, why would this compile? I mean, why can Expression and Func be used interchangeably as a parameter? Then, why does Expression work, and the Func version just hangs?

Note: The only difference between the above method and this one is the method parameter (Expression vs. 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();
}
like image 731
Bob Horn Avatar asked Apr 04 '12 18:04

Bob Horn


1 Answers

The Expression version calls Queryable.Where which generates an expression tree, which (when enumerated by ToList) is translated to sql and executed on the database server. Presumably, the database server will avail itself of an index based on the filter criteria, to avoid reading the whole table.

The Func version calls Enumerable.Where which (when enumerated by ToList) loads the whole table (what you perceive as a hang) and then runs the filter criteria against the in-memory objects.

like image 88
Amy B Avatar answered Nov 16 '22 10:11

Amy B