Eager loading with Criteria

In this recipe, we'll show you how to use CriteriaQueries 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 EagerLoadingWithCriteria in the project.
  2. Add a new class named Recipe to the folder:
    using NH4CookbookHelpers.Queries;
    using NH4CookbookHelpers.Queries.Model;
    using NHibernate;
    using NHibernate.Transform;
    
    namespace QueryRecipes.EagerLoadingWithCriteria
    {
        public class Recipe : QueryRecipe
        {
            protected override void Run(ISession session)
            {
                var book = session.CreateCriteria<Book>()
                    .SetFetchMode("Publisher", FetchMode.Join)
                    .UniqueResult<Book>();
    
                Show("Book:", book);
    
                var movies = session.CreateCriteria<Movie>()
                    .SetFetchMode("Actors", FetchMode.Join)
                    .SetResultTransformer(
                     Transformers.DistinctRootEntity)
                    .List<Movie>();
    
                Show("Movies:", movies);
            }
        }
    }
  3. Run the application and start the EagerLoadingWithCriteria 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 Eager loading with LINQ recipe. Take special note of the caveats mentioned in the There's more… section.

In this recipe, we use two criteria queries and both load related data eagerly. The first one loads one book and its related Publisher in one single query. The call to SetFetchMode specifies the "path" to the property we want to be included, and importantly sets the FetchMode to Join.

The second query is very similar, but this time we're fetching a collection property. Since the joined table will cause more rows to be returned, we need to tell NHibernate that we only want one of each movie and not as many movies as there are actors. This is done with a result transformer (discussed further in Chapter 5, Improving performance), called DistinctRootEntityTransformer, which reduces the result set to the list we want.

What if we also wanted to eager load a property of one of our related entities? That can be done too, as long as the entire path to said property is also eagerly loaded.

session.CreateCriteria<Movie>()
  .SetFetchMode("Actors", FetchMode.Join)
  .SetFetchMode("Actors.BookAboutTheRole", FetchMode.Join)

In other words, we need to specify that both Actors and Actors.BookAboutTheRole should be eagerly loaded.

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

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