Should I always return IQueryable<> instead of IList<>?
I came across this post while I was looking for things to improve performance. Currently, in my application we are returning IList<>
all over the place. Is it a good idea to change all of these returns to AsQueryable()
?
Here is what I found -
AsQueryable()
- Context needs to be open and you cannot control the lifetime of the database context it need to be disposed properly. Also it is deferred execution('faster filtering' as compared to Lists)IList<>
- This should be preferred overList<>
as it provides a barebone and lightweight implementation.
Also when should be one preferred over another ? I know the basics but I am sorry I am still not clear when and how should we use them correctly in an application. It would be great to know this as the next time I would try to keep it in mind before returning anyt开发者_Go百科hing..Thanks a lot.
Basically, you should try to reference the widest type you need. For example, if some variable is declared as List<...>
, you put a constraint for the type of the values that can be assigned to it. It may happen that you need only sequential access, so it would be enough to declare the variable as IEnumerable<...>
instead. That will allow you to assign the values of other types to the variable, as well as the results of LINQ operations.
If you see that your variable needs access by index, you can again declare it as IList<...>
and not just List<...>
, allowing other types implementing IList<...>
be assigned to it.
For the function return types, it depends upon you. If you think it's important that the function returns exactly List<...>
, you declare it to return exactly List<...>
. If the only important thing is access to the result by index, perhaps you don't need to constrain yourself to return exactly List<...>
, you may declare return type as IList<...>
(but return actually an instance of List<...>
in this implementation, and possibly of some another type supporting IList<...>
later). Again, if you see that the only important thing about the return value of your function is that it can be enumerated (and the access by index is not needed), you should change the function return type to IEnumerable<...>
, giving yourself more freedom.
Now, about AsQueriable
, again it depends on your logic. If you think that possible delayed evaluation is a good thing in your case, as it may aid to avoid the unneeded calculations, or you intend to use it as a part of some another query, you use it. If you think that the results have to be "materialized", i.e., calculated at this very moment, you would better return a List<...>
. You would especially need to materialize your result if the calculation later may result in a different list!
With the database a good rule of thumb is to use AsQueriable
for the short-term intermediate results, but List
for the "final" results which will be used within some longer time. Of course having a non-materialized query hanging around makes closing the database impossible (since at the moment of actual evaluation of the the database should be still open).
if you do not intend to do any further queries over sql server then you should return IList because it produces in-memory data
If you are concerned about performance you should also try to run your queries on as few DB requests as possible and cache the most used queries. It is very common to reduce significantly the request process time using batch approachs.
Which ORM do you use to retrieve data from DB? If you use NHibernate, see this post about how to use Future, Multi Criteria 1, Multi Criteria 2 and Multi Query.
Greetings.
精彩评论