AutoMapper
是C#
里面的一款超级优秀的属性映射工具,减少了大量的对象转换代码,节省了宝贵的时间。
简单的映射
对于如下的简单映射,我们是非常熟悉的:
Student
类的定义如下:
public class Student
{
public int Age { get; set; }
public string Name { get; set; }
public string Location{ get; set; }
}
我们所需要的StudentDto
定义如下:
public class Student
{
public int MyAge { get; set; }
public string MyName { get; set; }
public string MyLocation{ get; set; }
}
很简单,我们只要定义如下的AutoMapper Configuration 映射关系即可:
public class AutoMapperConfig:Profile
{
public AutoMapperConfig()
{
CreateMap()
.ForMember(d => d.Age, opt => opt.MapFrom(src => src.MyAge))
.ForMember(d => d.Name, opt => opt.MapFrom(src => src.MyName))
.ForMember(d=>d.Location,opt=>opt.MapFrom(src=>src.MyLocation));
}
}
ForPath 映射
那么,现在问题来了,如果Student
类中包含了Address
子类,应该如何映射呢?这时候的Address
类如下:
public class Address
{
public string City { get; set; }
public string Province { get; set; }
}
而此时的Student
类的定义如下:
public class Student
{
public int MyAge { get; set; }
public string MyName { get; set; }
public Address Address { get; set; }
}
但是我们所需要的StudentDto
定义确实下面的样子:
public class StudentDto
{
public int MyAge { get; set; }
public string MyName { get; set; }
public string MyCity{ get; set; }
}
StudentDto
的City
属性与Student
的Address
属性下面的City
属性对应。
我们可以想当然的认为此时的AutoMapper Configuration 映射关系是下面样子肯定行:
public class AutoMapperConfig:Profile
{
public AutoMapperConfig()
{
CreateMap()
.ForMember(d => d.Age, opt => opt.MapFrom(src => src.MyAge))
.ForMember(d => d.Name, opt => opt.MapFrom(src => src.MyName))
.ForMember(d=>d.Address.City,opt=>opt.MapFrom(src=>src.MyCity));
}
}
然后,事与愿违,需要将StudentDto
的MyCity
属性与Student
的Address
属性下面的City
属性对应映射方式由ForMember
改为ForPath
方式即可,正确的操作如下:
public class AutoMapperConfig:Profile
{
public AutoMapperConfig()
{
CreateMap()
.ForMember(d => d.Age, opt => opt.MapFrom(src => src.MyAge))
.ForMember(d => d.Name, opt => opt.MapFrom(src => src.MyName))
.ForPath(d=>d.Address.City,opt=>opt.MapFrom(src=>src.MyCity));
}
}
IEnumerable 集合属性映射
渐渐地,我们在开发的时候有、又会遇到类似如下的Student
定义:
public class Student
{
public int MyAge { get; set; }
public string MyName { get; set; }
public IEnumerable Myhobbies { get; set; }
}
而此时的StudentDto
定义如下:
public class Student
{
public int MyAge { get; set; }
public string MyName { get; set; }
public IEnumerable hobbies { get; set; }
}
这里与上面两种的区别在于,这里包含集合属性的映射:
同样,我们想当然地认为,认为此时的AutoMapper Configuration 映射关系是下面样子:
public class AutoMapperConfig:Profile
{
public AutoMapperConfig()
{
CreateMap()
.ForMember(d => d.Age, opt => opt.MapFrom(src => src.MyAge))
.ForMember(d => d.Name, opt => opt.MapFrom(src => src.MyName))
.ForPath(d=>d.hobbies ,opt=>opt.MapFrom(src=>src.Myhobbies ));
}
}
然而,在运行的会抛出异常。
其实在这里集合属性正确的映射方式如下:
public class AutoMapperConfig:Profile
{
public AutoMapperConfig()
{
CreateMap, Student>()
.ForMember(d => d.Myhobbies , opt => opt.MapFrom(src => src));
CreateMap, StudentDto>()
.ForMember(d => d.hobbies , opt => opt.MapFrom(src => src));
CreateMap()
.ForMember(d => d.Age, opt => opt.MapFrom(src => src.MyAge))
.ForMember(d => d.Name, opt => opt.MapFrom(src => src.MyName))
.ForPath(d=>d.hobbies ,opt=>opt.MapFrom(src=>src.Myhobbies ));
}
}
也就是说,需要将这里的属性集合类型IEnumerable
与属性名进行一次映射。
注意:Student
与StudentDto
的集合属性类型IEnumerable
都分别需要和属性名进行映射。