迷恋弦哥

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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(); } } }
posted on 2012-06-28 11:24  迷恋弦哥  阅读(538)  评论(0)    收藏  举报