2012-04-04 13 views
6

我有一个数据访问类,花了我一段时间才能工作。对于我的应用程序,我需要获取不同类型的SQL Server表,其中WHERE子句只与列名有所不同:有些列是read_time,其他列是ReadTime,其他列是LastModifiedTime。所以我想我会通过WHERE子句,所以我不需要为50个不同的表创建一个新的方法。它看起来很简单,而且很有效,但我不明白。为什么Func <>和Expression <Func<>>可互换?为什么一个人在我的情况下工作?

这种方法,以表达<>作为参数,工作原理:

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可以互换使用作为参数?那么,为什么表达能够工作,并且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(); 
} 
+3

这与答案相结合本身就是对“表达树的要点是什么”的一些非常好的回答。问题的风格。 +1 Q&A – 2012-04-04 18:11:27

回答

12

的表达版本调用Queryable.Where其产生表达式树,其(当由ToList列举)被转换为SQL和在数据库服务器上执行。据推测,数据库服务器将利用基于过滤标准的索引,以避免读取整个表格。

的Func键版本调用Enumerable.Where这(当ToList列举)加载整个表(你所认为的挂起),然后运行对内存中的对象的筛选条件。

+0

Ahhhhhhhhhhhh ... NICE。总体感觉。谢谢! – 2012-04-04 18:14:07

相关问题