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.
MappingWithFluent
to the MappingRecipes
project.FluentNHibernate
package using Nuget package manager console.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); } } }
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); } } }
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(); } } }
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(); } } }
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" } } }); } } }
MappingWithFluent
recipe.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.
18.220.88.62