6

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

此方法以 Expression<> 作为参数,有效:

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

1 回答 1

12

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

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

于 2012-04-04T18:06:17.780 回答