Creating mappings fluently
创建Fluent mappings
使用Fluent NHibernate的优点:使得你在使用NHibernate映射模型时,可以使用强类型的C#语法。在本小节中,将演示如何使用Fluent NHibernate映射我们的Eg.Core模型(实体类)。
准备工作:
从Fluent NHibernate的官网:http://fluentnhibernate.org/downloads下载Fluent NHibernate二进制发布包,注意选择一个和你所用的NHibernate相兼容的版本。Fluent NHibernate下载包中同样也包含必须的NHibernate程序集,或许你想用她们替代原有的程序集。
将FluentNHibernate.dll从下载包解压到Lib文件夹中。
完成前面有关Eg.Core的模型和映射的部分
如何去做:
1.创建一个新的类库项目,并命名为Eg.FluentMappings.
2.添加FluentNHibernate.dll引用.
3.把Eg.Core项目中的Entity.cs, Product.cs, Book.cs, Movie.cs , 和 ActorRole.cs 复制到Eg.FluentMappings项目
4.复制的时候,更改这些类的namespaces:从Eg.Core改为Eg.FluentMappings.
5.在Entity.cs中,更改属性Version的修饰符:从protected该public.
6.添加一个新的文件夹,并命名为Mappings .
7.创建一个新的类,并命名为ProductMapping,代码如下:
View Code
1 using FluentNHibernate.Mapping; 2 namespace Eg.FluentMappings.Mappings 3 { 4 public class ProductMapping : ClassMap<Product> 5 { 6 public ProductMapping() 7 { 8 Id(p => p.Id) 9 .GeneratedBy.GuidComb(); 10 DiscriminateSubClassesOnColumn("ProductType"); 11 Version(p => p.Version); 12 NaturalId() 13 .Not.ReadOnly() 14 .Property(p => p.Name); 15 Map(p => p.Description); 16 Map(p => p.UnitPrice) 17 .Not.Nullable(); 18 } 19 } 20 }
8.创建一个新的类,并命名为BookMapping,代码如下:
View Code
1 using FluentNHibernate.Mapping; 2 namespace Eg.FluentMappings.Mappings 3 { 4 public class BookMapping : SubclassMap<Book> 5 { 6 public BookMapping() 7 { 8 Map(p => p.Author); 9 Map(p => p.ISBN); 10 } 11 } 12 }
9.创建一个新的类,并命名为BookMapping,代码如下:
View Code
1 using FluentNHibernate.Mapping; 2 namespace Eg.FluentMappings.Mappings 3 { 4 public class MovieMapping : SubclassMap<Movie> 5 { 6 public MovieMapping() 7 { 8 Map(m => m.Director); 9 HasMany(m => m.Actors) 10 .KeyColumn("MovieId") 11 .AsList(l => l.Column("ActorIndex")); 12 } 13 } 14 }
10.创建一个新的类,并命名为ActorRoleMapping,代码如下:
View Code
1 using FluentNHibernate.Mapping; 2 namespace Eg.FluentMappings.Mappings 3 { 4 public class ActorRoleMapping : ClassMap<ActorRole> 5 { 6 public ActorRoleMapping() 7 { 8 Id(ar => ar.Id) 9 .GeneratedBy.GuidComb(); 10 Version(ar => ar.Version); 11 Map(ar => ar.Actor) 12 .Not.Nullable(); 13 Map(ar => ar.Role) 14 .Not.Nullable(); 15 } 16 } 17 }
分析原理
Fluent NHibernate提供了两种映射方法: Fluent mapping syntax 和 auto-mapping.在本展示中使用前者。每一个实体类都有一个映射类与之对应。
由于映射的语法要求类成员必须是可访问的,所以我们必须将Version属性由protected改为public。当然,Fluent NHibernate也有其他技巧来解决这个问题,欲了解详细的内容,请访问http://wiki.fluentnhibernate.org/Fluent_mapping_private_properties
根类的映射继承自ClassMap,子类的映射继承自SubclassMap。Fluent NHibernate默认使用table-per-subclass(每个类型分别一张表,基类表共享)类型的映射方法,如果我们要使用table-per-class(所有类型同一张表)映射方法,需要在Product表中添加一个指定字段以中区分出子类,此处为:DiscriminateSubClassesOnColumn。Fluent NHibernate不支持table-per-concrete-class(每个具体的子类一张表)映射方法。
我们指定Product的natural ID(自然主键)为Not.ReadOnly(),就像在XML mapping文件中设置mutable="true"一样。
属性映射使用Map()方法,等同于在XML mapping文件中的设置property元素。
One-to-many(1对多)的集合关系映射使用HasMany()方法,然后调用AsMap(), AsBag(), AsSet()或是AsList()方法。AsList()方法中再调用Column()方法指定list的索引列。
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(); } } }


浙公网安备 33010602011771号