Creating mappings fluently

The Fluent NHibernate project brings strongly-typed C# fluent syntax mappings to NHibernate. In this recipe, I'll show you how to map our Eg.Core model using Fluent NHibernate.

Getting ready

Download the Fluent NHibernate binary from the Fluent NHibernate website at http://fluentnhibernate.org/downloads. Select a version that's compatible with the specific build of NHibernate you are using. The Fluent NHibernate download also contains the necessary assemblies for NHibernate. You may wish to use them instead.

Extract FluentNHibernate.dll from the downloaded ZIP file to the Lib folder.

Complete the previous Eg.Core model and mapping recipes.

How to do it...

  1. Create a new class library project named Eg.FluentMappings.
  2. Add a reference to FluentNHibernate.dll.
  3. Copy Entity.cs, Product.cs, Book.cs, Movie.cs, and ActorRole.cs from Eg.Core to the new Eg.FluentMappings.
  4. In the copied model, change the namespaces from Eg.Core to Eg.FluentMappings.
  5. In Entity.cs, change the Version property from protected to public.
  6. Add a new folder named Mappings.
  7. Create a new class named ProductMapping with the following code:
    using FluentNHibernate.Mapping;
    
    namespace Eg.FluentMappings.Mappings
    {
      public class ProductMapping : ClassMap<Product>
      {
    
        public ProductMapping()
        {
          Id(p => p.Id)
            .GeneratedBy.GuidComb();
          DiscriminateSubClassesOnColumn("ProductType");
          Version(p => p.Version);
          NaturalId()
            .Not.ReadOnly()
            .Property(p => p.Name);
          Map(p => p.Description);
          Map(p => p.UnitPrice)
            .Not.Nullable();
        }
    
      }
    }
  8. Create a new class named BookMapping with the following code:
    using FluentNHibernate.Mapping;
    
    namespace Eg.FluentMappings.Mappings
    {
      public class BookMapping : SubclassMap<Book>
      {
    
        public BookMapping()
        {
          Map(p => p.Author);
          Map(p => p.ISBN);
        }
    
      }
    }
  9. Create a new class named MovieMapping with the following code:
    using FluentNHibernate.Mapping;
    
    namespace Eg.FluentMappings.Mappings
    {
      public class MovieMapping : SubclassMap<Movie>
      {
    
        public MovieMapping()
        {
          Map(m => m.Director);
          HasMany(m => m.Actors)
            .KeyColumn("MovieId")
            .AsList(l => l.Column("ActorIndex"));
        }
    
      }
    }
  10. Create a new class named ActorRole with the following code:
    using FluentNHibernate.Mapping;
    
    namespace Eg.FluentMappings.Mappings
    {
      public class ActorRoleMapping : ClassMap<ActorRole>
      {
    
        public ActorRoleMapping()
        {
          Id(ar => ar.Id)
            .GeneratedBy.GuidComb();
          Version(ar => ar.Version);
          Map(ar => ar.Actor)
            .Not.Nullable();
          Map(ar => ar.Role)
            .Not.Nullable();
        }
    
      }
    }

How it works...

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

Because the mapping syntax requires class members to be accessible, we must change the Version property from protected to public. Fluent NHibernate also includes some tricks to work around this issue. They're explained fully in the wiki at http://wiki.fluentnhibernate.org/Fluent_mapping_private_properties.

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. Fluent NHibernate doesn't support table-per-concrete-class hierarchies.

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
  • Mapping with ConfORM
..................Content has been hidden....................

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