[英]IQueryable vs IEnumerable: is IQueryable always better and faster?
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
替换,它可以更快更高效?
DBSet<T>
has two flavors of Where
( IQueryable
and IEnumerable
). DBSet<T>
有两种Where
( IQueryable
和IEnumerable
)。 Is there a way to call the IEnumerable
version because the IQueryable
is called by default, without calling ToList()
? 有没有办法调用IEnumerable
版本,因为默认情况下调用IQueryable
而不调用ToList()
?
- If the
IQueryable
perform the query Expression in the server rather than fetching all records likeIEnumerable
, whyIQueryable
not replaced byIEnumerable
where it can be faster and more efficient? 如果IQueryable
在服务器中执行查询表达式而不是像IEnumerable
那样获取所有记录,那么为什么IQueryable
不会被IEnumerable
替换,它可以更快更高效?
IQueryable
and IEnumerable
represent two different things. IQueryable
和IEnumerable
代表两种不同的东西。 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
(答案)时,将会收到类似于“不支持指定方法”的错误。
DBSet<T>
has two flavors ofWhere
(IQueryable
andIEnumerable
).DBSet<T>
有两种Where
(IQueryable
和IEnumerable
)。 is there a way to call theIEnumerable
version because theIQueryable
is called by default, without callingToList()
? 有没有办法调用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.Where
和Queryable.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.