NHibernate剖析:Mapping篇之Mapping-By-Code(2):運用ModelMapper

來源:互聯網
上載者:User

標籤:

運用Mapping-By-Code

我們先定義一個非常簡單的Domain模型,一個int類型的Id屬性和一個string類型的Something屬性,用來代碼映射:

public class MyClass{    public int Id { get; set; }    public string Something { get; set; }}
1.基本映射

ModelMapper提供一種基本映射方式:使用Class方法對實體類MyClass特定映射:

  • 屬性Id映射為資料庫主鍵,對應的列名稱為MyClassId、主鍵建置原則是HighLow策略。
  • 屬性Something映射為資料庫普通欄位,其長度為150。

最後調用CompileMappingForAllExplicitAddedEntities方法顯式所有映射的實體(這裡是MyClass)編譯為HbmMapping對象並輸出,也可以使用CompileMappingFor方法指定實體類型。

[Test]public void BasicMappingRegistration(){    var mapper = new ModelMapper();    mapper.Class<MyClass>(cm =>    {        cm.Id(myclass => myclass.Id, map =>        {            map.Column("MyClassId");            map.Generator(Generators.HighLow);        });        cm.Property(myclass => myclass.Something, map => map.Length(150));    });    var hbmMapping = mapper.CompileMappingForAllExplicitAddedEntities();    //var hbmMapping = mapper.CompileMappingFor(new[] {typeof (MyClass)});    hbmMapping.ShowInConsole();}

NHibernate對於代碼映射提供很強的靈活性,你可以像你希望的那樣隨意去組織映射:例如class-by-class方式、不同的映射點在不同的地方等等。

例如下面代碼映射,分開去配置映射,NHibernate對重複的屬性不重複映射,去合并映射:

[Test]public void WhenDuplicatePropertiesDoesNotDuplicateMapping(){    var mapper = new ModelMapper();    mapper.Class<MyClass>(cm =>    {        cm.Id(myclass => myclass.Id, map => map.Column("MyClassId"));        cm.Id(myclass => myclass.Id, map => map.Generator(Generators.HighLow));        cm.Property(myclass => myclass.Something);        cm.Property(myclass => myclass.Something, map => map.Length(150));    });    var hbmMapping = mapper.CompileMappingForAllExplicitAddedEntities();    hbmMapping.ShowInConsole();}

你甚至也可以在兩個不同地方去映射整個實體類:

[Test]public void WhenDuplicateClassDoesNotDuplicateMapping(){    var mapper = new ModelMapper();    mapper.Class<MyClass>(cm =>    {        cm.Id(myclass => myclass.Id, map => map.Generator(Generators.HighLow));        cm.Property(myclass => myclass.Something);    });    mapper.Class<MyClass>(cm =>    {        cm.Id(myclass => myclass.Id, map => map.Column("MyClassId"));        cm.Property(myclass => myclass.Something, map => map.Length(150));    });    var hbmMapping = mapper.CompileMappingForAllExplicitAddedEntities();    hbmMapping.ShowInConsole();}
2.Conformist映射

ModelMapper提供另外一種Conformist映射方式:class-by-class方式,即每個類定義一個類去映射,然後調用AddMapping方法把映射加入ModelMapper對象。

private class MyClassMap : ClassMapping<MyClass>{    public MyClassMap()    {        Id(myclass => myclass.Id, map =>        {            map.Column("MyClassId");            map.Generator(Generators.HighLow);        });        Property(myclass => myclass.Something, map => map.Length(150));    }}[Test]public void ConformistMappingRegistration(){    var mapper = new ModelMapper();    mapper.AddMapping<MyClassMap>();    var hbmMapping = mapper.CompileMappingForAllExplicitAddedEntities();    hbmMapping.ShowInConsole();}

上面的映射如果查看其輸出結果,都是一樣:

3.約定

ModelMapper提供了很多事件監聽器,可以通過它擴充ModelMapper。其中就是自訂約定。其實上面定義的映射從設計思想上面說也是一種約定,暫時可以稱作特定約定(Specific-Convetions)

以Before開頭的事件監聽稱作前置約定(Pre-Conventions)。從人性化角度看前置約定(Pre-Conventions)比較民主(democratic),我們映射時可以使用特定約定(Specific-Convetions)

以After開頭的事件監聽稱作後置約定(Post-Conventions)或者稱作Hard-Conventions。從人性化角度看後置約定(Post-Conventions)就比較共和(republican),不管前面怎麼特定,到最後一律使用後置約定(Post-Conventions)所規定的"條約"。

例如下面例子使用前置約定(Pre-Conventions):

[Test]public void MapClassWithConventions(){    var mapper = new ModelMapper();    //option:Pre-Conventions    mapper.BeforeMapClass +=        (mi, t, map) => map.Id(x => x.Column((t.Name + "id").ToUpper()));    mapper.BeforeMapProperty +=        (mi, propertyPath, map) => map.Column(propertyPath.ToColumnName().ToUpper());    mapper.Class<MyClass>(cm =>    {        cm.Id(myclass => myclass.Id, map => map.Generator(Generators.HighLow));        cm.Property(myclass => myclass.Something);    });    var hbmMapping = mapper.CompileMappingForAllExplicitAddedEntities();    hbmMapping.ShowInConsole();}

使用後置約定(Post-Conventions):

[Test]public void MapClassWithHardConventions(){    var mapper = new ModelMapper();    //option:Hard-Conventions    mapper.AfterMapClass +=        (mi, t, map) => map.Id(x => x.Column((t.Name + "id").ToUpper()));    mapper.AfterMapProperty +=        (mi, propertyPath, map) => map.Column(propertyPath.ToColumnName().ToUpper());    mapper.Class<MyClass>(cm =>    {        cm.Id(myclass => myclass.Id, map =>                             {                                 map.Column("MyClassId");                                 map.Generator(Generators.HighLow);                             });        cm.Property(myclass => myclass.Something, map => map.Column("Whatever"));    });    var hbmMapping = mapper.CompileMappingForAllExplicitAddedEntities();    hbmMapping.ShowInConsole();}

這個例子最終主鍵的映射的列名稱為MYCLASSID,Something映射的列名稱為SOMETHING。但是其思想有些不同。

結語

NHibernate3.2新增的Mapping-By-Code(代碼映射),這篇文章結合上篇的原理從整體大運用Mapping-By-Code(代碼映射)功能,有個整體方向。

著作權聲明:本文為博主http://www.zuiniusn.com 原創文章,未經博主允許不得轉載。

NHibernate剖析:Mapping篇之Mapping-By-Code(2):運用ModelMapper

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.