Configuring the second-level cache with code

NHibernate also provides an option for cache configuration with the NHibernate.Cfg.Loquacious namespace. In this recipe, we'll show you how to configure the second-level cache with code.

Getting ready

Complete the Getting Ready instructions at the beginning of. Chapter, Queries.

How to do it...

  1. Add a reference to NHibernate.Caches.SysCache using NuGet Package Manager Console.
  2. Add a new folder named CachingWithCode to the project.
  3. Add a new class named Recipe to the folder:
    using NH4CookbookHelpers.Queries;
    using NH4CookbookHelpers.Queries.Model;
    using NHibernate;
    using NHibernate.Caches.SysCache;
    using NHibernate.Cfg;
    
    namespace QueryRecipes.CachingWithCode
    {
      public class Recipe : QueryRecipe
      {
      }
    }
  4. In Recipe, add the following method:
    protected override void Configure(Configuration nhConfig)
    {
      nhConfig
        .Cache(x =>
        {
          x.Provider<SysCacheProvider>();
          x.UseQueryCache = true;
        })
        .EntityCache<Product>(c =>
        {
          c.Strategy = EntityCacheUsage.ReadWrite;
          c.RegionName = "hourly";
        })
        .EntityCache<ActorRole>(c =>
        {
          c.Strategy = EntityCacheUsage.ReadWrite;
          c.RegionName = "hourly";
        })
        .EntityCache<Movie>(c => c.Collection(
        movie => movie.Actors,
        coll =>
        {
          coll.Strategy = EntityCacheUsage.ReadWrite;
          coll.RegionName = "hourly";
        }));
    }
  5. In Recipe, add the two following methods:
    protected override void Run(ISessionFactory sessionFactory)
    {
      ShowMoviesBy(sessionFactory, "Steven Spielberg");
      ShowMoviesBy(sessionFactory, "Steven Spielberg");
    }
    
    private void ShowMoviesBy(ISessionFactory sessionFactory, string director)
    {
      using (var session = sessionFactory.OpenSession())
      {
        using (var tx = session.BeginTransaction())
        {
          var movies = session.QueryOver<Movie>()
            .Where(x => x.Director == director)
            .Cacheable()
            .List();
          Show("Movies found:", movies);
          tx.Commit();
        }
      }
    }
  6. Run the application and start the CachingWithCode recipe.

How it works...

  1. For details on how the caching behaves, see the preceding recipe, Use the second-level cache.
  2. By calling the following code, we not only specify the provider we want to use (cache.provider_class) but also specify that the query cache should be enabled (cache.use_query_cache):
    .Cache(x =>
            {
                x.Provider<SysCacheProvider>();
                x.UseQueryCache = true;
            })
  3. We also implicitly enable the second-level cache (cache.use_second_level_cache).
  4. We configure the class cache for our Product hierarchy and ActorRole entities with the following code:
      .EntityCache<Product>(c =>
      {
        c.Strategy = EntityCacheUsage.ReadWrite;
        c.RegionName = "hourly";
      })
      .EntityCache<ActorRole>(c =>
      {
        c.Strategy = EntityCacheUsage.ReadWrite;
        c.RegionName = "hourly";
      })
  5. Finally, we configure the collection cache for our Actors collection with the following code:
    nhConfig
      .EntityCache<Movie>(c => c.Collection(
        movie => movie.Actors,
        coll =>
        {
          coll.Strategy = EntityCacheUsage.ReadWrite;
          coll.RegionName = "hourly";
        }));

Note how we call Collection(), passing an expression for our Actors collection, as well as the settings for our collection cache.

There's more…

Just as with XML mappings, it's perfectly possible to specify the class-level cache configuration in coded mappings.

  • For NHibernate's built in class mappings it looks similar to this:
    public class ProductMapping : ClassMapping<Product>
    {
      public ProductMapping()
      {
        …
        Cache(c =>
        {
          c.Usage(CacheUsage.ReadWrite);
          c.Region("hourly");
        });
      }
    }
    
    public class MovieMapping : SubclassMapping<Movie>
    {
      public MovieMapping()
      {
        ...
        Set(x => x.Actors, x =>
          {
            x.Cache(c =>
            {
              c.Usage(CacheUsage.ReadWrite);
              c.Region("hourly");
            });
          ...
          }
        , x => x.OneToMany());
      }
    }
  • For Fluent NHibernate:
    public class ProductMap : ClassMap<Product>
    {
      public ProductMap()
      {
        ...
        Cache.ReadWrite().Region("hourly");
      }
    }
    public class MovieMap : SubclassMap<Movie>
    {
      public MovieMap()
      {
        ...
        HasMany(x => x.Actors)
          .AsSet()
          .Cache.ReadWrite().Region("hourly");
      }
    }

See also

  • Use the second-level cache
..................Content has been hidden....................

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