C#IQueryable和IEnumerable的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#IQueryable和IEnumerable的区别相关的知识,希望对你有一定的参考价值。

参考技术A 一言以蔽之,本地数据源用IEnumerable,并且查询的逻辑可以直接用你所定义的方法的逻辑(因为有上下文),远程数据源用IQueryable,无法直接使用你所定义的方法的逻辑,必须先生成表达式树,查询由源对象处理。

IEnumerable 和 IQueryable

共有两组 LINQ 标准查询运算符,一组在类型为 IEnumerable<T> 的对象上运行,另一组在类型为 IQueryable<T> 的对象上运行。构成每组运算符的方法分别是 EnumerableQueryable 类的静态成员。这些方法被定义为作为方法运行目标的类型的“扩展方法”。这意味着可以使用静态方法语法或实例方法语法来调用它们。

              大家应该还记得,上节我们说过linq查询要执行在clr上师把查询语句变成扩展方法来执行,这两套东西不仅返回类型不同连所定义的扩展方法都不同,所以我们完全可以把这2套东西理解成完全不同的东西,那么,什么时候用IEnumerable<T>,什么时候用IQueryable<T>呢?让我们再来看看msdn的介绍:

             对于在内存中集合上运行的方法(即扩展 IEnumerable<T> 的那些方法),返回的可枚举对象将捕获传递到方法的参数。在枚举该对象时,将使用查询运算符的逻辑,并返回查询结果。

             与之相反,扩展 IQueryable <T> 的方法不会实现任何查询行为,但会生成一个表示要执行的查询的表达式树。查询处理由源 IQueryable<T> 对象处理。

             一言以蔽之,本地数据源用IEnumerable<T>,并且查询的逻辑可以直接用你所定义的方法的逻辑(因为有上下文),远程数据源用IQueryable<T>,无法直接使用你所定义的方法的逻辑,必须先生成表达式树,查询由源对象处理。

            下面我们再来看一个例子来证明这是两套完全不同的东西:

            首先是本地数据源:

            List<string> names = new List<string> { "Cai", "Wxied", "Beauty" };

            然后我们看看names的where方法

            VS的智能提示会告诉我们(sorry,这个地方实在不好截图,大家可以自己尝试,我先给大家描述下)这个扩展方法有2个重载,必须传入Func<T>,返回IEnumerable<T>。

再提一点知识,Func<T>叫谓语表达式,相当于一个委托,我认为,之所以可以直接传Func<T>是因为本地数据源可以直接执行方法的逻辑。

            再让我们来看看一个远程数据源:

            DataClasses1DataContext dataContext = new DataClasses1DataContext();

            dataContext.Customers.Where这个方法有4个重载。必须传入Expression<Func<T>>,返回IQueryable<T>。

             大家和上面对比一下,就会发现本地数据源和远程数据源的扩展方法完全不一样,而且远程数据源不能直接传Func<T>,必须用一个Expression来包装这个Func<T>,正好又从一个方面验证了我们之前所提到的知识。

以上是关于C#IQueryable和IEnumerable的区别的主要内容,如果未能解决你的问题,请参考以下文章

IQueryable和IEnumerable以及AsEnumerable()和ToList()的区别

IQueryable 和 IEnumerable 有啥区别 [重复]

IEnumerable 和 IQueryable

温故知新C#中 IEnumerable 与IQueryable

IQueryable 和 IEnumerable 之间差异的真实示例? [复制]

IQueryable和IEnumerable,IList的区别