为什么Func&lt;&gt;和表达式<func <>&gt;互换?为什么一个人在我的情况下工作?</func <>

时间:2012-04-04 18:04:13

标签: c# oop linq-to-sql generics

我有一个数据访问类,花了我一段时间才能开始工作。对于我的应用程序,我需要获得不同类型的SQL Server表,其中WHERE子句仅因列名而不同:某些列是read_time,其他列是ReadTime,其他列是LastModifiedTime。所以我想我会传入WHERE子句,所以我不需要为50个不同的表创建一个新方法。它看起来很简单,而且有效,但我不明白。

此方法,具有表达式&lt;&gt;作为参数,工作:

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();
}

现在,我正在尝试这种方式(下面)一段时间,它只会挂在最后一行(ToList())。首先,为什么要编译?我的意思是,为什么Expression和Func可以互换使用作为参数?那么,为什么Expression工作,而Func版本只是挂起?

注意:上述方法与此方法的唯一区别是方法参数(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();
}

1 个答案:

答案 0 :(得分:12)

Expression版本调用Queryable.Where,它生成一个表达式树(当由ToList枚举时)被转换为sql并在数据库服务器上执行。据推测,数据库服务器将利用基于过滤条件的索引,以避免读取整个表。

Func版本调用Enumerable.Where(当ToList枚举时)加载整个表(您认为是挂起),然后运行过滤条件内存中的对象。