AutoMapper----Custom Type converters

 一、AutoMapper

       AutoMapper是什么?AutoMapper是一个.NET的对象映射工具。

       映射什么?映射的场景有:领域对象与DTO之间的转换、数据库查询结果映射至实体对象。

       具体关于AutoMapper 的概念,这里就不再多说,场景详细请看。

  

  最近在项目的时候就遇到其中的一个场景:对象实体想DTO的转换。     底层使用的思想是ORM.在ORM中,与数据库交互用的Model模型是具有很多属性变量方法这些,而当我们与其它
系统(或系统中的其它结构)进行数据交互时,出于耦合性考虑或者安全性考虑或者性能考虑(总之就是各种考虑),
我们不希望直接将这个Model模型暴露给外界,这时我们会创建一个DTO模型(贫血模型)来保存数据并传递。
(DTO,Data Transfer Object)就是说只包含属性,只能保存必须的数据,没有其它任何的多余的方法数据什么的,
专门用于数据传递用的类型对象。

二、转换方式
     
     这样的一个场景,我们就需要一个方法来帮助我们来进行DTO和Entity之间转换。
    转换又分几种方式,一种就是比较简单的相同类型之间的转换。例如:Controls 转换成ControlsViewModel 

<span style="font-family:KaiTi_GB2312;font-size:18px;">public partial class Controls
    {
        public string ControlId { get; set; }
        public string ControlType { get; set; }
        public string ControlDesc { get; set; }
    }</span>
<span style="font-family:KaiTi_GB2312;font-size:18px;"> [DataContract]
    public class ControlsViewModel
    {
        [DataMember]
        public string ControlId { get; set; }
        /// <summary>
        /// 控件类型
        /// </summary>
        [DataMember]
        public string ControlType { get; set; }
        /// <summary>
        /// 控件描述
        /// </summary>
        [DataMember]
        public string ControlDesc { get; set; }
       
    }</span>

    可以看到两个实体中包含的属性的类型都是相同类型的,这样的转换我们只需要属性一一匹配就行了,方法参考

       还有另一种情形——实体中包含的属性类型不一样,即A 实体中包含的属性A1是 C类型的,但是B实体中与A1对应的B1是D类型的,这个时候,如何实现A1到B1的转换呢?

     如果你的C 和D 类型是 System的包含的已有类型,如:int ,string ,datatime ……这些,可以参考这里。

    今天的主题现在开始正式进入,这篇博客说的是自定义类型之间的转换。即:C ,D 不是System已包含的实体,是自己定义的。

  情景如下:实体模型如下,其中包含一个Controls 的自定义类型。 

<span style="font-family:KaiTi_GB2312;font-size:18px;">public partial class QueryProperties
    {
        public string QueryId { get; set; }
        public string PropertyName { get; set; }
        public string PropertyDesc { get; set; }
        public string ControlHtmlName { get; set; }
        public string ControlHtmlId { get; set; }
        public string IsShow { get; set; }
        public string EntityName { get; set; }
        public string EntityDesc { get; set; }
        public string IsCondition { get; set; }
    
        public virtual Controls Controls { get; set; }
    }</span>

  目标模型如下:跟实体模型QueryProperties不同的是,其中包含一个ControlViewModel的自定义类型来对应Controls实体。

<span style="font-family:KaiTi_GB2312;font-size:18px;">[DataContract]
    public class QueryPropertiesViewModel
    {
        [DataMember]
        public string QueryId { get; set; }
        [DataMember]
        public string PropertyName { get; set; }
        [DataMember]
        public string PropertyDesc { get; set; }
        [DataMember]
        public string ControlHtmlName { get; set; }
        [DataMember]
        public string ControlHtmlId { get; set; }
        [DataMember]
        public string IsShow { get; set; }
        [DataMember]
        public string EntityName { get; set; }
        [DataMember]
        public string EntityDesc { get; set; }
        [DataMember]
        public string IsCondition { get; set; }

        [DataMember]
        public virtual ControlsViewModel Controls { get; set; }
    }</span>

     如果单纯的使用:AutoMapper 中:Mapper.Map<Tsource,TDestination>(tSource) ,它会转换失败,告诉你类型不匹配。要想成功转换,我们第一步需要让Mapper认识Controls 和ControlViewModel 是一对的,可以相互转换。

添加如下声明代码:        

<span style="font-family:KaiTi_GB2312;font-size:18px;">              Mapper.CreateMap<ControlsViewModel, Controls>();</span>
        然后声明主体对象:                  
<span style="font-family:KaiTi_GB2312;font-size:18px;">             var expression = Mapper.CreateMap<QueryPropertiesViewModel,QueryProperties>();</span>
        指明匹配属性:

<span style="font-family:KaiTi_GB2312;font-size:18px;">             expression.ForMember(s => s.Controls, (map) => map.MapFrom(m => m.Controls));</span>
       开始转换:

<span style="font-family:KaiTi_GB2312;font-size:18px;">    QueryProperties enQueryProperties = Mapper.Map<QueryPropertiesViewModel, QueryProperties>(viewQueryProperties);</span>
 

   代码中,单个实体不和其他实体打交道的类少只有少,这就是我们所谓的实体级联转换。希望可以帮到你们。

你可能感兴趣的:(.net,orm,AutoMapper)