There are two different concepts how to recieve the data from the DB. In case of one-to-many (lists, dictionaries).
1) We can call NHibernate to get data by ID or reference (similar cases)
session.Get<Unit>(1);
In this case NHibernates injects all the properties not marked as lazy. So in your case, this will cause to eagerly load of the Parts as well.
the similar is the reference property: public virtual Unit Unit { get; set; }
of ane OtherObject
var otherObject = ... // get from session
var unit = otherObject.Unit; // the full Unit with all `Lazy="false"` properties is loaded
2) But we can also use the Criteria
(As in your case). However, this is different approach. In this case, we are explicitly saying that we want only work with Unit
Units = crit.Future<Unit>().ToList<Unit>();
This has many advantages:
- we can do efficient paging only on the
Unit
table - only the Unit is loaded (maybe the Parts won't be used)
- if Parts are used, they will be lazily loaded
But if really needed (regardles of side effects like inocrrect paging) we can also load the Parts in one select:
Units = crit
.SetFetchMode("Parts", FetchMode.Eager)
.Future<Unit>()
.ToList<Unit>();
Now is all populated at once.
3) The approach I would vote for (I am using 100%) is to let collection to be lazy, and assign the batch-size
19.1.5. Using batch fetching
EXTENDED
To show you how to change the mapping:
<map name="Parts" table="UnitParts" lazy="true" batch-size="25">
From that moment, your Util is lightweight. No Parts loaded, until really needed. If the session is opened during the whole request, once the Parts are touched, they will be loaded in one SELECT (if the page size of Utils is not larger then 25)
This approach is very efficient, becuase it uses the power of ORM - everything is lazy