AutoMapper 反向映射与展开
提示
从
6.1.0
版本开始,AutoMapper
现在支持更丰富的逆向映射支持。考虑到我们的实体如下:
public class Order {
public decimal Total { get; set; }
public Customer Customer { get; set; }
}
public class Customer {
public string Name { get; set; }
}
我们可以将其扁平化为一个 DTO
(数据传输对象):
public class OrderDto {
public decimal Total { get; set; }
public string CustomerName { get; set; }
}
我们可以在这两个方向上进行映射,包括展开操作(unflattening
):
var configuration = new MapperConfiguration(cfg => {
cfg.CreateMap<Order, OrderDto>()
.ReverseMap();
});
通过调用 ReverseMap
,AutoMapper
会创建一个包含展开操作的逆向映射配置:
var customer = new Customer {
Name = "Bob"
};
var order = new Order {
Customer = customer,
Total = 15.8m
};
var orderDto = mapper.Map<Order, OrderDto>(order);
orderDto.CustomerName = "Joe";
mapper.Map(orderDto, order);
order.Customer.Name.ShouldEqual("Joe");
展开操作仅在 ReverseMap
中配置。如果你需要展开功能,你必须先配置 Entity
到 Dto
,然后调用 ReverseMap
来创建从 Dto
到 Entity
的展开类型映射配置。
自定义逆向映射
AutoMapper
会根据原始的扁平化自动逆向映射 “Customer.Name” 自 “CustomerName”。如果你使用了 MapFrom
,AutoMapper
会尝试逆向这个映射:
cfg.CreateMap<Order, OrderDto>()
.ForMember(d => d.CustomerName, opt => opt.MapFrom(src => src.Customer.Name))
.ReverseMap();
只要 MapFrom
路径是成员访问器,AutoMapper
就会从相同的路径展开( CustomerName
=> Customer.Name
)。
如果你需要自定义这一点,对于逆向映射,你可以使用 ForPath
:
cfg.CreateMap<Order, OrderDto>()
.ForMember(d => d.CustomerName, opt => opt.MapFrom(src => src.Customer.Name))
.ReverseMap()
.ForPath(s => s.Customer.Name, opt => opt.MapFrom(src => src.CustomerName));
对于大多数情况,你不需要这样做,因为原始的 MapFrom
会被自动逆向处理。当获取和设置值的路径不同时,使用 ForPath
。
如果你不希望有展开行为,你可以移除对 ReverseMap
的调用并创建两个独立的映射。或者,你可以使用 Ignore
:
cfg.CreateMap<Order, OrderDto>()
.ForMember(d => d.CustomerName, opt => opt.MapFrom(src => src.Customer.Name))
.ReverseMap()
.ForPath(s => s.Customer.Name, opt => opt.Ignore());
IncludeMembers
ReverseMap
也与 IncludeMembers
和类似配置集成,
ForMember(destination => destination.IncludedMember, member => member.MapFrom(source => source))