Creating mappings fluently

Even before NHibernate added the possibility to provide mappings in code, the Fluent NHibernate project (FNH) delivered a strongly-typed, fluent syntax, as an alternative to XML mappings. It remains very popular and many NHibernate articles online show examples using FNH mappings. In this recipe, we will show you how to map our product model using Fluent NHibernate.

Getting ready

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

How to do it…

  1. Add a new folder named MappingWithFluent to the MappingRecipes project.
  2. Add a reference to the FluentNHibernate package using Nuget package manager console.
  3. Create a new class named ProductMap with the following code:
    using NH4CookbookHelpers.Mapping.Model;
    using FluentNHibernate.Mapping;
    
    
    namespace MappingRecipes.MappingWithFluent
    {
     public class ProductMap : ClassMap<Product>
     {
      public ProductMap()
      {
       Id(p => p.Id).GeneratedBy.GuidComb();
       Version(x => x.Version);
       NaturalId().Property(p => p.Name).Not.ReadOnly();
       DiscriminateSubClassesOnColumn("ProductType");
       Map(p => p.Description);
       Map(p => p.UnitPrice);
      }
     }
    }
  4. Create a new class named BookMap with the following code:
    using FluentNHibernate.Mapping;
    using NH4CookbookHelpers.Mapping.Model;
    
    namespace MappingRecipes.MappingWithFluent
    {
     public class BookMap : SubclassMap<Book>
     {
    
      public BookMap()
      {
       DiscriminatorValue("Book");
       Map(p => p.Author);
       Map(p => p.ISBN);
      }
     }
    }
  5. Create a new class named MovieMap with the following code:
    using FluentNHibernate.Mapping;
    using NH4CookbookHelpers.Mapping.Model;
    
    namespace MappingRecipes.MappingWithFluent
    {
     public class MovieMap : SubclassMap<Movie>
     {
      public MovieMap()
      {
       DiscriminatorValue("Movie");
       Map(m => m.Director);
       HasMany(m => m.Actors)
         .KeyColumn("MovieId")
         .AsList(l => l.Column("ActorIndex"))
         .Cascade.AllDeleteOrphan();
      }
     }
    }
  6. Create a new class named ActorRoleMap with the following code:
    using FluentNHibernate.Mapping;
    using NH4CookbookHelpers.Mapping.Model;
    
    namespace MappingRecipes.MappingWithFluent
    {
     public class ActorRoleMap : ClassMap<ActorRole>
     {
    
      public ActorRoleMap()
      {
       Id(ar => ar.Id).GeneratedBy.GuidComb();
       Map(ar => ar.Actor).Not.Nullable();
       Map(ar => ar.Role).Not.Nullable();
      }
     }
    }
  7. Add a new class named Recipe with the following code:
    using FluentNHibernate;
    using NH4CookbookHelpers.Mapping;
    using NH4CookbookHelpers.Mapping.Model;
    using NHibernate;
    using NHibernate.Cfg;
    
    namespace MappingRecipes.MappingWithFluent
    {
     public class Recipe : BaseMappingRecipe
     {
      protected override void Configure(Configuration cfg)
      {
       cfg.AddMappingsFromAssembly(GetType().Assembly);
      }
    
      protected override void AddInitialData(ISession session)
      {
       session.Save(new Movie()
       {
        Name = "Fluent mapping - the movie",
        Description = "Go with the flow.",
        UnitPrice = 300,
        Actors = { new ActorRole { Actor = "FNH", Role = "The mapper" } }
       });
      }
     }
    }
  8. Run the application and start the MappingWithFluent recipe.

How it works…

Fluent NHibernate provides two methods for mappings: Fluent mapping syntax and automapping. In this recipe, we use the Fluent mapping syntax. Each entity class has a corresponding mapping class.

Mappings for root classes are inherited from ClassMap and subclasses in a class hierarchy inherit from SubclassMap. By default, Fluent NHibernate creates a table-per-subclass hierarchy. To use a table-per-class hierarchy instead, we specify DiscriminateSubClassesOnColumn in Product.

When mapping the natural id of Product, we specify .Not.ReadOnly(). This is the same as setting mutable="true" in the XML mapping.

Properties are mapped using the Map() method, which is equivalent to the property element in XML mappings.

One-to-many collections are mapped using the HasMany() method, followed by AsMap(), AsBag(), AsSet(), or AsList(). AsList uses the Column() method to specify a column name for the list index.

See also

  • Mapping a class with XML
  • Creating class hierarchy mappings
  • Mapping a one-to-many relationship
  • Setting up a base entity class
  • Bidirectional one-to-many class relationships
  • Handling versioning and concurrency
  • Creating mappings fluently
..................Content has been hidden....................

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