c# Linq查询中的IEnumerable<T>和IQueryable<T>

Linq查询方法一共提供了两类扩展方法,在System.Linq命名空间下,有两个静态类:
①、Enumerable类,它针对继承了IEnumerable<T>接口的集合类进行扩展
②、Queryable类,它针对继承了IQueryable<T>接口的集合类进行扩展

稍加观察我们会发现,接口IQueryable<T>实际也是继承了IEnumerable<T>接口的,所以,致使这两个接口的方法在很大程度上是一致的.

那么,微软为什么要设计出两套扩展方法呢?
我们知道,Linq查询从功能上来讲实际上可分为三类:Linq to OBJECTS、Linq to SQL、Linq to XML

设计两套接口的原因正是为了区别对待Linq to OBJECTS、Linq to SQL,两者对于查询的处理在内部使用的是完全不同的机制:
①、针对LINQ to OBJECTS时,使用Enumerable中的扩展方法对本地集合进行排序和查询等操作,查询参数接受的是Func<>,Func<>叫做谓语表达式,相当于一个委托.
②、针对LINQ to SQL时,则使用Queryable中的扩展方法,它接受的参数是Expression<>,Expression<>用于包装Func<>,LINQ to SQL引擎最终会将表达式树转化成为相应的SQL语句,然后在数据库中执行.

那么,到底什么时候使用IQueryable<T>,什么时候使用IEnumerable<T>呢?
简单表述就是:本地数据源用IEnumerable<T>,远程数据源用IQueryable<T>

在使用IQueryable<T>和IEnumerable<T>的时候还需要注意一点:
①、IEnumerable<T>查询的逻辑可以直接用我们自己所定义的方法
②、IQueryable<T>则不能使用自定义的方法,它必须先生成表达式树,查询由Linq to SQL引擎处理.在使用IQueryable<T>查询的时候,如果使用自定义的方法,则会抛出异常.

摘自《编写高质量代码改善C#程序的157个建议》一书

posted @ 2021-07-01 15:41  狼王爷  阅读(561)  评论(0编辑  收藏  举报