简体   繁体   English

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

[英]IQueryable vs IEnumerable: is IQueryable always better and faster?

  1. If the IQueryable interface performs the query expression in the server rather than fetching all records like IEnumerable , why is IQueryable not replaced by IEnumerable where it can be faster and more efficient? 如果IQueryable接口在服务器中执行查询表达式而不是获取IEnumerable类的所有记录,为什么IQueryable不会被IEnumerable替换,它可以更快更高效?

  2. DBSet<T> has two flavors of Where ( IQueryable and IEnumerable ). DBSet<T>有两种WhereIQueryableIEnumerable )。 Is there a way to call the IEnumerable version because the IQueryable is called by default, without calling ToList() ? 有没有办法调用IEnumerable版本,因为默认情况下调用IQueryable而不调用ToList()

  1. If the IQueryable perform the query Expression in the server rather than fetching all records like IEnumerable , why IQueryable not replaced by IEnumerable where it can be faster and more efficient? 如果IQueryable在服务器中执行查询表达式而不是像IEnumerable那样获取所有记录,那么为什么IQueryable不会被IEnumerable替换,它可以更快更高效?

IQueryable and IEnumerable represent two different things. IQueryableIEnumerable代表两种不同的东西。 Think of a IQueryable as a "question", it does not have any results itself. IQueryable视为一个“问题”,它本身没有任何结果。 A IEnumerable is an "answer", it only has data connected to it but you can't tell what generated that data. IEnumerable是一个“答案”,它只有连接到它的数据,但你不知道是什么产生了这些数据。

It is not that a IQueryable is "faster" per say, it just allows you to put your filtering and projections in to the "question" you ask to the SQL server and let it return only the answers it needs to (In the form of a IEnumerable by calling .ToList() or similar). 并不是说IQueryable是“更快”的说法,它只是允许你将过滤和投影放到你向SQL服务器询问的“问题”中,让它只返回它需要的答案(以形式通过调用.ToList()或类似的IEnumerable )。

If you only use a IEnumerable the only question you can ask is "Give me everything you know" then on the answer it gives you you perform your filtering and projections. 如果您只使用IEnumerable ,您可以问的唯一问题是“给我你知道的一切”,然后在答案上给你执行过滤和预测。 That is why IQueryable is considered faster, because there is a lot less data that needs to be processed because you where able to ask a more specific question to the server. 这就是为什么IQueryable被认为更快的原因,因为需要处理的数据要少得多,因为你可以向服务器提出更具体的问题。

The reason IQueryable has not replaced IEnumerable everywhere is because the thing you are asking a question has to be able to understand the question you are asking it. IQueryable没有在任何地方取代IEnumerable的原因是因为您提出问题的事情必须能够理解您提出的问题。 It takes a lot of work to be able to parse every possible thing you could ask it to filter or project on so most implementations limit themselves to only common things they know they need to be able to answer . 能够解析您可能要求它过滤或投影的每个可能的事情需要做很多工作,因此大多数实现仅限于他们知道他们需要能够回答的常见事物 For example in Entity Framework when you ask a question it does not understand how to handle you will get a error that says something similar to "Specified method is not supported" when you try to get a IEnumerable (an answer) from the IQueryable . 例如,在实体框架中,当您提出一个不理解如何处理的问题时,当您尝试从IQueryable获取IEnumerable (答案)时,将会收到类似于“不支持指定方法”的错误。

  1. DBSet<T> has two flavors of Where ( IQueryable and IEnumerable ). DBSet<T>有两种WhereIQueryableIEnumerable )。 is there a way to call the IEnumerable version because the IQueryable is called by default, without calling ToList() ? 有没有办法调用IEnumerable版本,因为默认情况下调用IQueryable ,而不调用ToList()

The class DBSet<T> has no Where method on it at all . DBSet<T>根本没有Where方法 The two Where functions come from two extension methods, Enumerable.Where and Queryable.Where . 两个Where函数来自两个扩展方法, Enumerable.WhereQueryable.Where You can force it to use the Enumerable overload by casting the object to a IEnumerable<T> before you call the extension method. 在调用扩展方法之前,可以通过将对象强制转换为IEnumerable<T>来强制它使用Enumerable重载。 However do remember, Queryable.Where filters the question, Enumerable.Where only filters the result. 但请记住, Queryable.Where过滤问题, Enumerable.Where只过滤结果。

It is wasteful to ask for results from the server to then just throw them away, so I would not recommend doing this. 从服务器请求结果然后将它们扔掉是浪费的,所以我不建议这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM