2017-04-14 24 views
0
  1. 如果IQueryable接口执行服务器查询表达式,而不是像获取所有IEnumerable记录,为什么IQueryableIEnumerable替代它可以更快,更高效?IQueryable与IEnumerable:IQueryable总是更好更快?

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

回答

7
  1. 如果IQueryable在服务器上而不是 获取像IEnumerable所有记录进行查询表达式,为什么不IQueryable取代 通过IEnumerable它可以更快,更高效?

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。例如,在实体框架中,如果您提出的问题不明白如何处理,则会出现类似于的错误“指定的方法不受支持”当您尝试从IQueryable获得IEnumerable(答案)时。

  • DBSet<T>具有WhereIQueryableIEnumerable)两种口味。 有没有办法调用IEnumerable版本,因为默认情况下调用了 IQueryable,而不调用ToList()
  • DBSet<T>没有Where method on it at all。两个Where函数来自两个扩展方法,Enumerable.WhereQueryable.Where。在调用扩展方法之前,可以强制它使用Enumerable超载,方法是将对象强制转换为IEnumerable<T>。不过请记住,Queryable.Where过滤问题,Enumerable.Where只过滤结果。

    从服务器请求结果然后把它们扔掉是浪费的,所以我不会推荐这样做。

    +0

    你的例子(问题和答案)很好,正如我从它理解的那样,'IQueryable'没有用,直到我将它转换为IEnumerable列表才能得到理想的答案 –

    相关问题