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

运用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 原创文章,未经博主允许不得转载。

时间: 2024-10-10 17:42:49

NHibernate剖析:Mapping篇之Mapping-By-Code(2):运用ModelMapper的相关文章

NHibernate3剖析:Mapping篇之Mapping概览

Mapping概述 NHibernate作为典型的ORM工具,我们使用时通常是先定义Domain,再为Domain映射数据库关系,NHibernate映射是使用XML文件形式的.本篇从整体上了解下NHibernate Mapping处理过程及我们编写方式. Mapping处理过程 当我们Confrontation NHibernate时,NHibernate对Mapping部分到底做了什么事情呢? 解析读取Mapping文件 将Mapping文件反序列化(Deserialize)为XmlDese

NHibernate3剖析:Mapping篇之集合映射基础(3):List映射

系列引入 NHibernate3.0剖析系列分别从Configuration篇.Mapping篇.Query篇.Session策略篇.应用篇等方面全面揭示NHibernate3.0新特性和应用及其各种应用程序的集成,基于NHibernte3.0版本号. 假设你还不熟悉NHibernate.能够高速阅读NHibernate之旅系列文章导航系列入门,假设你已经在用NHibernate了,那么请跟上NHibernate3.0剖析系列吧. NHibernate专题:http://kb.cnblogs.c

NHibernate3剖析:Mapping篇之ConfORM实战(3):OneToOne语义

系列引入 NHibernate3剖析系列分别从Configuration篇.Mapping篇.Session篇.Core篇.Tool篇.Practice篇.Extension篇等方面全面揭示NHibernate3版本内容.特性及其应用,完全基于NHibernte3版本. NHibernate专题:http://kb.cnblogs.com/zt/nhibernate/ NHibernate官方站点:http://nhforge.org/ NHibernate参考文档:http://nhforge

NHibernate3剖析:Mapping篇之ConfORM实战(2):原理

系列引入 NHibernate3剖析系列分别从Configuration篇.Mapping篇.Session篇.Core篇.Tool篇.Practice篇.Extension篇等方面全面揭示NHibernate3版本内容.特性及其应用,完全基于NHibernte3版本. NHibernate专题:http://kb.cnblogs.com/zt/nhibernate/ NHibernate官方站点:http://nhforge.org/ NHibernate参考文档:http://nhforge

NHibernate3剖析:Mapping篇之集合映射基础(4):Map映射

系列引入 NHibernate3.0剖析系列分别从Configuration篇.Mapping篇.Query篇.Session策略篇.应用篇等方面全面揭示NHibernate3.0新特性和应用及其各种应用程序的集成,基于NHibernte3.0版本.如果你还不熟悉NHibernate,可以快速阅读NHibernate之旅系列文章导航系列入门,如果你已经在用NHibernate了,那么请跟上NHibernate3.0剖析系列吧. NHibernate专题:http://kb.cnblogs.com

NHibernate3剖析:Mapping篇之集合映射基础(2):Bag映射

系列引入 NHibernate3.0剖析系列分别从Configuration篇.Mapping篇.Query篇.Session策略篇.应用篇等方面全面揭示NHibernate3.0新特性和应用及其各种应用程序的集成,基于NHibernte3.0版本.如果你还不熟悉NHibernate,可以快速阅读NHibernate之旅系列文章导航系列入门,如果你已经在用NHibernate了,那么请跟上NHibernate3.0剖析系列吧. NHibernate专题:http://kb.cnblogs.com

NHibernate系列文章二十七:NHibernate Mapping之Fluent Mapping(附程序下载)

摘要 从这一节起,介绍NHibernate Mapping的内容.前面文章都是使用的NHibernate XML Mapping.NHibernate XML Mapping是NHibernate最早最成熟的Mapping方法.其他的Mapping方法都是基于XML Mapping的思想进行的“变种”,要么暂时不能完全像XML Mapping那样功能丰富.其他的Mapping方法目前包括:Fluent Mapping.Attribute Mapping和Mapping by Convention

elasticsearch篇之mapping

2018年05月17日 18:01:37 lyzkks 阅读数:444更多 个人分类: Elastic stack 版权声明:文章内容来自于网络和博主自身学习体会,转载请注明出处,欢迎留言大家一起讨论学习~~ https://blog.csdn.net/sinat_35930259/article/details/80354732 什么是mapping mapping是类似于数据库中的表结构定义,主要作用如下: 定义index下的字段名 定义字段类型,比如数值型.浮点型.布尔型等 定义倒排索引相

Building Maintainable Software-java篇之 Write Clean Code

Building Maintainable Software-java篇之 Write Clean Code Writing clean code is what you must do in order to call yourself a professional. -Robert C. Martin Guideline: ? Write clean code. ? Do this by not leaving code smells behind after development wor

第九章 Normal Mapping and Displacement Mapping

第九章 Normal Mapping and Displacement Mapping 本章主要讲述两种图形学技术,支持在不增加objects的poly primitive的情况下,在场景中增加更多的细节.第一种是normal mapping,通过创建一些"fake" geometry(虚设的多边形图元)模拟光照作用.第二种是displacement mapping,根据纹理数据moving vertices actually(与"fake"相对应,这里指真实的移动