我们在之前的文章中提到了ORM,然后用到了EF,今天我们再介绍一种实体转换关系的模型AutoMapper。
一、是什么
AutoMapper是一个.NET的对象映射工具。主要作用是进行领域对象与贫血模型之间的转换、数据库查询结果映射至实体对象。
什么是贫血模型?贫血模型(DTO,Data Transfer Object,就是说只包含属性,只能保存必须的数据,木有其它任何的多余的方法数据,专门用于数据传递用的类型对象)。
那这是什么意思呢,比如在ORM中,与数据库交互用的Model模型是具有很多属性变量方法的实体。而当我们与其它系统(或系统中的其它结构)进行数据交互时,出于耦合性考虑或者安全性考虑或者性能考虑(总之就是各种考虑),我们不希望直接将这个Model模型传递给它们,这时我们会创建一个贫血模型保存数据并传递。
也正是这个原因,我们才需要在Model模型和DTO实体之间做相互的转换。
二、怎么用
1、两个实体的属性完全一样
在应用它之前我们先要在vs中引用它。点击工具下的库程序包管理器,选择程序包管理控制台!然后输入Install-PackageAutoMapper。或者右击解决方案,在nuget管理中找到AutoMapper,安装, 然后在引入AutoMapper,就可以放心的使用了
Model实体
<span style="font-size:18px;">namespace testautomapper
{
//学生源实体类
public class studentSource
{
public string name { get; set; }
public int age {get;set;}
public string sex { get; set; }
}
}</span>
DTO实体
<span style="font-size:18px;">namespace testautomapper
{
//学生目标实体类
public class studentPurpost
{
public string name { get; set; }
public string age { get; set; }
public string sex { get; set; }
}
}</span>
单个实体转换过程
<span style="font-size:18px;"><span style="font-size:18px;">namespace testautomapper
{
class Program
{
static void Main(string[] args)
{
//创建映射规则 ,第一个参数为源实体(Model),第二个为目标实体(DTO)
Mapper.CreateMap<studentSource, studentPurpost>();
//创建一个源实体
studentSource sSource = new studentSource
{
name = "崔晓光",
age = 23,
sex = "男"
};
//进行转换 ,得到目标实体(DTO)
var sPurpost = Mapper.Map<studentPurpost>(sSource);
Console.WriteLine(sPurpost.name + sPurpost.sex + sPurpost.age); //输出目标实体的属性
}
}
</span>}</span>
多个实体转换过程(实体集)
<span style="font-size:18px;"><span style="font-size:18px;">namespace testautomapper
{
class Program
{
static void Main(string[] args)
{
//创建一个转换关系规则
Mapper.CreateMap<studentSource, studentPurpost>();
//创建一个实体集合
List<studentSource> list = new List<studentSource>();
studentSource s = new studentSource
{
name = "cuixiaoguang",
age = 13,
sex = "nan"
};
list.Add(s);
//进行转换
List<studentPurpost> sPurpostList = Mapper.Map<List<studentSource>, List<studentPurpost>>(list);
Console.WriteLine(sPurpostList[0].age + sPurpostList[0].name + sPurpostList[0].sex);
}
}
}</span></span>
2、两个实体的属性不完全一样
Model实体
<span style="font-size:18px;">namespace testautomapper
{
//学生源实体类
public class studentSource
{
public string Sname { get; set; }
public int age {get;set;}
public string sex { get; set; }
}
}</span>
DTO实体
<span style="font-size:18px;">namespace testautomapper
{
//学生目标实体类
public class studentPurpost
{
public string Pname { get; set; }
public string age { get; set; }
public string sex { get; set; }
}
}</span>
实体转换(实体集合同理)
AutoMapper使用ForMember来指定每一个字段的映射规则:
引用:The each custom member configuration uses an action delegate to configure each member.
还好有强大的lambda表达式,规则的定义简单明了。
<span style="font-size:18px;"><span style="font-size:18px;">namespace testautomapper
{
class Program
{
static void Main(string[] args)
{
//创建映射规则 ,第一个参数为源实体(Model),第二个为目标实体(DTO)
Mapper.CreateMap<studentSource, studentPurpost>();
//定义实体中不同的属性,使之对应
map.ForMember(d => d.Sname, opt => opt.MapFrom(s => s.Pname));
//创建一个源实体
studentSource sSource = new studentSource
{
Sname = "崔晓光",
age = 23,
sex = "男"
};
//进行转换 ,得到目标实体(DTO)
var sPurpost = Mapper.Map<studentPurpost>(sSource);
Console.WriteLine(sPurpost.name + sPurpost.sex + sPurpost.age); //输出目标实体的属性
}
}
</span>}</span>
3、两个实体的属性完全不一样
Model实体
<span style="font-size:18px;">namespace testautomapper
{
//学生源实体类
public class studentSource
{
public string Sname { get; set; }
public int Sage {get;set;}
public string Ssex { get; set; }
}
}</span>
DTO实体
<span style="font-size:18px;">namespace testautomapper
{
//学生目标实体类
public class studentPurpost
{
public string Pname { get; set; }
public string Page { get; set; }
public string Psex { get; set; }
}
}</span>
实体转换
AutoMapper使用ConstructUsing来指定每一个字段的映射规则
<span style="font-size:18px;"><span style="font-size:18px;">namespace testautomapper
{
class Program
{
static void Main(string[] args)
{
//创建映射规则 ,第一个参数为源实体(Model),第二个为目标实体(DTO)
Mapper.CreateMap<studentSource, studentPurpost>();
//定义实体中所有不同的属性,使之对应
map.ConstructUsing(s => new studentPurpost
{
Pname= s.Sname,
Page= s.Sage,
Psex= s.Ssex
});
//创建一个源实体
studentSource sSource = new studentSource
{
Sname = "崔晓光",
age = 23,
sex = "男"
};
//进行转换 ,得到目标实体(DTO)
var sPurpost = Mapper.Map<studentPurpost>(sSource);
Console.WriteLine(sPurpost.name + sPurpost.sex + sPurpost.age); //输出目标实体的属性
}
}
</span>}</span>
这里还可以用 ForMember,一个个的将实体属性对应,不过感觉这样比较麻烦所以就不写了