灵活使用IEnumerable接口和IQueryable接口

Linq的所有功能,基本上都是基于IEnumerable接口类型来提供的,用IEnumerable接口处理本地集合还行,当场景切换到远程数据源时,势必要把远程的所有数据都读取到本地,数据量小的时候问题不大,但若是有几万笔、几十万笔数据,或是网络速度受限时,会变得很严重。

为了不影响数据访问性能以及将网络的流量需求降到最小的情况下,支持LINQ所需的功能,LINQ只用IEnumerable是无法处理的,而必须要额外提供一个针对远程数据源的专用接口。为了达到这样的需求,微软内建立了一个介于IEnumerable和数据源之间的提供者IQueryable接口。

区分AsEnumerable()与AsQueryable()

     当使用AsEnumerable()将IQueryable转换为IEnumerable时,就变成对内存内的集合进行操作了,而不需要将查询传回到远程数据源,速度会加快很多。相反使用AsQueryable()将IEnumerable转化为IQueryable时,所有的LINQ操作都会被转换成对远程数据源的查询,而不对目前在内存中的集合进行操作,所以真正的查询会在远程数据源进行,与本地的内存集合无关。
因此,若是对远程数据查询,一开始应该使用IQueryable,或是查询前先使用AsQueryable()将查询目标转换成远程数据源,再进行查询,而查询之后若要重复对查询结果进行LINQ操作,则应该使用AsEnumerable()将查询目标转换回内存集合,如此一来性能会比对远程数据源发出数次查询要好得多
 
其中在判断数据源是否为空时,针对远程数据源,使用Any()来判断有无数据是最好的选择,因为相对于Count(),不需要完整计数,只要判断符合条件的数据是否存在一笔即可。
针对本地集合,使用Count()和Any()几乎没有性能上的差异。

你可能感兴趣的:(c#)