Eager loading with QueryOver

In this recipe, we'll show you how to use QueryOver queries to eager load the child collections of our query results.

Getting ready

Complete the Getting Ready instructions at the beginning of this chapter.

How to do it…

  1. Create a new folder named EagerLoadingWithQueryOver in the project.
  2. Add a new class named Recipe in the folder:
    using NH4CookbookHelpers.Queries;
    using NH4CookbookHelpers.Queries.Model;
    using NHibernate;
    using NHibernate.Transform;
    
    namespace QueryRecipes.EagerLoadingWithQueryOver
    {
        public class Recipe : QueryRecipe
        {
            protected override void Run(ISession session)
            {
                var book = session.QueryOver<Book>()
                    .Fetch(x => x.Publisher).Eager
                    .SingleOrDefault();
    
                Show("Book:", book);
    
                var movies = session.QueryOver<Movie>()
                    .Fetch(x => x.Actors).Eager
                    .OrderBy(x => x.Name).Asc
                    .TransformUsing(
                     Transformers.DistinctRootEntity)
                    .List();
                Show("Movies:", movies);
            }
        }
    }
  3. Run the application and start the EagerLoadingWithQueryOver recipe.
  4. Inspect the query log to see how the related entities have been included in the queries.

How it works…

For a detailed explanation of the eager loading mechanism, see the recipe Eager loading with LINQ. Take special note of the caveats mentioned in the There's more… section.

Also read the How it works… section of the previous recipe. Since QueryOver is based on criteria queries, the same logic applies.

QueryOver replaces the SetFetchMode method of criteria queries with the convenient Fetch method, which expects a lambda expression pointing to the property we want to eager load. This method call must be followed by the "fluent" property Eager, which specifies that we indeed want this fetch to be an eager load.

Just as with the criteria queries, an eager load of a collection property effectively requires that we also specify a result transformer. This is done by adding TransformUsing(Transformers.DistinctRootEntity) to the call chain.

Should we want to include yet another level to the eager loading, as we did with .SetFetchMode("Actors.BookAboutTheRole") in the preceding recipe, we need to twist the lambda expression a bit:

.Fetch(x => x.Actors).Eager
.Fetch(x => x.Actors.First().BookAboutTheRole).Eager

It may look a bit strange, but the call to First() is needed to allow the lambda to point to a property of ActorRole. If the Actors collection type exposes indexed accessing x.Actors[0]. BookAboutTheRole works just as well.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.19.243