问题
If the
IQueryable
interface performs the query expression in the server rather than fetching all records likeIEnumerable
, why isIQueryable
not replaced byIEnumerable
where it can be faster and more efficient?DBSet<T>
has two flavors ofWhere
(IQueryable
andIEnumerable
). Is there a way to call theIEnumerable
version because theIQueryable
is called by default, without callingToList()
?
回答1:
- 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
and IEnumerable
represent two different things. Think of a IQueryable
as a "question", it does not have any results itself. A IEnumerable
is an "answer", it only has data connected to it but you can't tell what generated that data.
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).
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. 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.
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. 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
.
DBSet<T>
has two flavors ofWhere
(IQueryable
andIEnumerable
). is there a way to call theIEnumerable
version because theIQueryable
is called by default, without callingToList()
?
The class DBSet<T>
has no Where method on it at all. The two Where
functions come from two extension methods, Enumerable.Where and 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. However do remember, Queryable.Where
filters the question, Enumerable.Where
only filters the result.
It is wasteful to ask for results from the server to then just throw them away, so I would not recommend doing this.
来源:https://stackoverflow.com/questions/43419228/iqueryable-vs-ienumerable-is-iqueryable-always-better-and-faster