本节内容

  • Mapping-By-Code概览
  • 运用ModelMapper
  • 结语
  • 参考资料

Mapping-By-Code概览

上一篇文章介绍了Mapping-By-Code(代码映射)的原理,这篇文章结合上篇的原理运用Mapping-By-Code(代码映射)。为了更有效的学习代码映射,这篇文章使用单元测试的方式,每一个测试用例代表某一功能实现,并且为了 直观的认识HbmMapping对象,我把HbmMapping对象序列化为字符串写入标准输出流,为此定义一个名为ShowInConsole的扩展方法。

public static class HbmMappingExtensions
{public static void ShowInConsole(this HbmMapping mapping){Console.WriteLine(mapping.AsString());}
}

运用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-Conventionsmapper.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-Conventionsmapper.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(代码映射)功能,有个整体方向。

参考资料

Fabio Maulo:NHibernate 3.2 mapping by code

Fabio Maulo:NHibernate 3.2: (part 2) mapping by code

转载于:https://www.cnblogs.com/lyj/archive/2011/04/10/inside-nh-mapping-by-code-apply.html

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

  1. 训练时发生的错误:Couldn‘t open shared file mapping: <000001910A228862>, error code: <1455>

    今天在运行TTSR时第14个epoch时发生了以下错误: 看到一篇博客有写: RuntimeError: Couldn't open shared file mapping: <torch_37 ...

  2. elasticsearch篇之mapping

    什么是mapping mapping是类似于数据库中的表结构定义,主要作用如下: 定义index下的字段名 定义字段类型,比如数值型.浮点型.布尔型等 定义倒排索引相关的设置,比如是否索引.记录pos ...

  3. Duwamish深入剖析-配置篇

    Duwamish深入剖析-配置篇 摘要: 本文详细介绍了Duwamish网上电子书店的Web.config配置文件的结构处理方式以及用途,阐述了配置文件的各功能模块中的作用. 目录: 引言 配置节处理 ...

  4. 查询优化器内核剖析第一篇

    查询优化器内核剖析第一篇 查询优化器内核剖析第一篇 查询优化器内核剖析第二篇:产生候选执行计划&执行计划成本估算 查询优化器内核剖析第三篇:查询的执行与计划的缓存 & Hint提示 查 ...

  5. ElasticSearch为索引库添加静态映射报:Failed to parse mapping [properties]: Root mapping definition has unsupport

    代码 PUT /my_index {"mappings": {"properties": {"title": {"type&quo ...

  6. [Elasticsearch] Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters

    一.ES7报错 Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters 原因:es7不建议 ...

  7. C语言的底层逻辑剖析函数篇(其二),0基础搞定函数,初识函数递归,超详解

    这里写目录标题 C语言的底层逻辑剖析函数篇(其二),0基础搞定函数,初识函数递归,超详解 开篇语 函数的调用(嵌套调用和链式访问) 1.嵌套调用 2.函数的链式访问 函数的声明和定义 函数声明和定义分 ...

  8. NHibernate剖析:Mapping篇之Mapping-By-Code(1):概览

    ModelMapper概述 NHibernate3.2版本号集成Mapping-By-Code(代码映射),其设计思想来源于ConfORM.代码总体构思基于"Loquacious" ...

  9. 【es】es 分布式一致性原理剖析 节点篇

    1.概述 好文章:Elasticsearch分布式一致性原理剖析(一)-节点篇 前言 "Elasticsearch分布式一致性原理剖析"系列将会对Elasticsearch的分布式 ...

  10. 初识NHibernate(配置篇)

    Nhibernate算是比较成熟的一个ORM框架,想想用过的NET中的ORM,算起来大致有以下几种 1.ADO.NET Entity Framework 2.Nhibernate 3.Linq to ...

最新文章

  1. python入门简介
  2. opencv+python机读卡识别(四)百度API进行数字识别
  3. MySQL模拟:线上误update的恢复
  4. 不止一个人犯错,这种 Github 不要写在简历上!
  5. 【Python基础】一文搞定pandas的数据合并
  6. 数据结构排序算法实验报告_[数据结构与算法系列]排序算法(二)
  7. CORS 跨域-同源策略
  8. awesome-go:很全的go语言资源合集
  9. 移动流媒体业务的技术与标准
  10. Mac下VirtualBox虚拟机Win7与主机共享文件夹
  11. 不到6年“拼”活近8亿用户 拼多多还在狂奔
  12. python param_python发送带param的post请求
  13. linux gettimeofday 头文件,linux-时间编程-time、gmtime、localtime、asctime、ctime、gettimeofday、sleep、usleep...
  14. 怎么计算算法复杂度 big O
  15. 深圳活用大数据提升气象服务
  16. 安卓小程序——猜数字游戏
  17. 打开QQ音乐检测不到声卡
  18. /dev/sda is entire device, not just one partition. Refusing to make a filesystem here
  19. aria2自动更新BT Tracker服务器列表脚本
  20. 异步4月新书,送出一本你爱的!

热门文章

  1. IDEA用maven创建springMVC项目和配置(XML配置和Java配置)
  2. 又一款性能调优神器,真香!
  3. 打开游戏要运行19.8亿次 if 语句?黑客嘲讽RockStar游戏代码太烂了
  4. 架构师成长计划|如何利用云原生构建一个企业级高可用架构?
  5. 2017年最受欢迎的15大Python库有哪些?
  6. 【干货】阿里直播平台的架构演进
  7. pandas (loc、iloc、ix)的区别
  8. es6箭头函数使用场景导致的一些问题
  9. 在地图上点击一下,在图层上画一个点,并显示相关的信息
  10. 最新县及县以上行政区划代码(截止2008年12月31日)