IQueryable vs IEnumerable:IQueryable总是更好更快吗?

时间:2017-04-14 21:01:20

标签: c# linq ienumerable iqueryable

  1. 如果IQueryable接口在服务器中执行查询表达式而不是提取IEnumerable之类的所有记录,为什么IQueryable不会被IEnumerable替换为DBSet<T>可以更快,更有效率吗?

  2. Where有两种IQueryableIEnumerableIEnumerable)。有没有办法调用IQueryable版本,因为默认情况下会调用ToList()而不调用{{1}}?

1 个答案:

答案 0 :(得分:12)

  
      
  1. 如果IQueryable在服务器中执行查询表达式   而不是提取IEnumerable之类的所有记录,为什么IQueryable没有   被IEnumerable取代,它可以更快,更有效率吗?
  2.   

IQueryableIEnumerable代表两种不同的东西。将IQueryable视为“问题”,它本身没有任何结果。 IEnumerable是一个“答案”,它只有连接到它的数据,但你无法分辨产生该数据的是什么。

并不是说IQueryable每个说法“更快”,它只是允许你将过滤和投影放到你向SQL服务器询问的“问题”中,让它只返回答案吧需要(通过调用IEnumerable或类似内容以.ToList()的形式)。

如果您只使用IEnumerable唯一可以问的问题是“给我你知道的一切”然后在答案上给你进行过滤和预测。这就是为什么IQueryable被认为更快的原因,因为需要处理的数据要少得多,因为您可以向服务器提出更具体的问题。

IQueryable到处都没有替换IEnumerable的原因是因为您提出的问题必须能够理解您提出的问题。需要做很多工作才能解析您可能要求它过滤或投影的所有可能的事情,以便大多数实现limit themselves to only common things they know they need to be able to answer。例如,在实体框架中,当您提出一个不理解如何处理的问题时,当您尝试获取{{1>时,会收到类似“不支持指定方法”的错误来自IEnumerable的答案。

  
      
  1. IQueryable有两种DBSet<T>WhereIQueryable)。   有没有办法调用IEnumerable版本,因为   默认情况下会调用IEnumerable,而不调用IQueryable
  2.   

班级ToList()没有Where method on it at all。这两个DBSet<T>函数来自两个扩展方法Enumerable.WhereQueryable.Where。在调用扩展方法之前,可以通过将对象强制转换为Where来强制它使用Enumerable重载。但请记住,IEnumerable<T>过滤了问题,Queryable.Where仅过滤结果。

从服务器请求结果然后将它们扔掉是浪费的,所以我不建议这样做。