NHibernate IList or List?
-
28-06-2021 - |
Domanda
I've looked around Stackoverflow and seen a couple questions related to NHibernate IList vs List. I have a question of my own...
Since the purpose of IList is to have a lazyloaded list, what purpose does it serve returning from a repository. After all if you ToList() your repository call, you are creating a definitive object? So therefore regardless if your method is returning an IList or a List, there is no more lazy loading involved, correct?
Soluzione
If your repository returns an IQueryable, the results will be retrieved first time you enumerate it. If you call ToList() on it, it will retrieve the results at this moment, because ToList will enumerate the IQueryable.
Now, lazy loading is not necessarily impacted by this behavior : suppose you have Customers and Orders. Each customer has a property named CustomerOrders, which is marked as lazy loaded. That means that when you load your list of customers, the orders are retrieved only if you try to enumerate the CustomerOrders property for each Customer. So if you just do a ToList() on your GetCustomers() method's return value, it has no effect on the lazy loading of CustomerOrders
Altri suggerimenti
You're pretty much correct, but are confusing some concepts so I'll take it from the top.
You are correct that .ToList()
materializes
things.
IList
is just an abstract interface for a materialized list.
NHibernate requires IList
in some cases because it proxies things. When using session.QueryOver
etc., you'll use the List()
extension method to return an IList
(which is materialized) or Future()
to return an IEnumerable
(lazy).
The QueryOver
is pretty stable and complete and well paved.
On the Linq provider side, you use session.Query
, and you can either stay at the IQueryable
level to have a 'spec of a query', IEnumerable
for lazy or IList
for materialized items. Normally you'll use ToList()
to materialize, and AsEnumerable()
(or a cast / type conversion) to get to IEnumerable
. NB I cannot make the statement I made re QueryOver about the LINQ provider.