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.
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.
Eg.FluentMappings
.FluentNHibernate.dll
.Entity.cs
, Product.cs
, Book.cs
, Movie.cs
, and ActorRole.cs
from Eg.Core
to the new Eg.FluentMappings
.Eg.Core
to Eg.FluentMappings
.Entity.cs
, change the Version
property from protected
to public
.Mappings
.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(); } } }
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); } } }
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")); } } }
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(); } } }
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.
3.142.199.181