Lazy loading allows you to not have to specify what you want to hydrate. The collections will be populated "lazily" at the time you access them. Your above query will only fetch a single row: John. When you access john.Classes
, NHibernate will execute another query behind the scenes to fetch John's classes. Then when you access the biology.Students
property, NHibernate will execute another query to populate that collection... and so on.
You definitely do want lazy-loading on this relationship (which is the default, by the way). If you turned lazy loading off, then this would do exactly what you're saying you want to avoid - NHibernate would know that it's not allowed to lazily load these collections, so it would start working to load them as soon as you loaded a student, which could potentially end up loading all of the data in these three tables, and in a very inefficient manner with lots of round-trips to the database.
If you know that all you want is "John, with Algebra and Biology", then you should add these lines to your query:
.SetFetchMode("Classes", FetchMode.Eager)
.SetResultTransformer(Transformers.DistinctRootEntity)
The SetFetchMode
tells NHibernate to use left outer joins to pre-populate the student.Classes
collection. The DistintRootEntity
tells NHibernate to not return the duplicate students that will be generated by the left outer join.