Automapper - 将 属性 映射到集合
Automapper - map property to collection
来源类:
public class ApplicationDriverFormVM
{
public ApplicationDriverAddressFormVM PresentAddress { get; set; }
public List<ApplicationDriverAddressFormVM> PreviousAddresses { get; set; }
}
public class ApplicationDriverAddressFormVM
{
[Required]
[StringLength(256)]
[Display(Name = "Address")]
public string Address { get; set; }
[Required]
[StringLength(256)]
[Display(Name = "City")]
public string City { get; set; }
//.....
}
目的地类:
public class ApplicationDriverDomain
{
public List<ApplicationDriverAddressDomain> Addresses { get; set; }
}
public class ApplicationDriverAddressDomain
{
public int Id { get; set; }
public string Address { get; set; }
public string City { get; set; }
//....
public bool IsPresentAddress { get; set; }
}
所以,我想将 PresentAddress(一个对象)和 PreviousAddresses(集合)映射到 Addresses 属性(集合),其中每个元素都有 IsPresentAddress 属性,这应该是真的,如果它PreviousAddresses 映射元素被映射为 PresentAddress 和 false。我试着写这样的地图基本规则:
CreateMap<ViewModels.ApplicationDriverFormVM, ApplicationDriverDomain>();
CreateMap<ViewModels.ApplicationDriverAddressFormVM, ApplicationDriverAddressDomain>();
当然,它不能正常工作。怎么做到的?
这可以通过 ForMember
扩展方法来完成。
这是一种快速而肮脏的方式来获得你想要的东西。它创建了一个新的 ApplicationDriverAddressFormVM
组合列表来映射,但如果您浏览文档,您可能会找到更优雅的内容。
Mapper.CreateMap<ApplicationDriverFormVM, ApplicationDriverDomain>()
.ForMember(dest => dest.Addresses, opt => opt.MapFrom(src => src.PreviousAddresses.Union(new List<ApplicationDriverAddressFormVM>() { src.PresentAddress })));
Mapper.CreateMap<ApplicationDriverAddressFormVM, ApplicationDriverAddressDomain>();
经过进一步调查,我发现了以下方法。它使用 ResolveUsing
选项。同样,这很粗糙,只使用了我发现的第一个功能。您应该进一步探索 IMemberConfigurationExpression
界面,看看还有哪些其他选项
Mapper.CreateMap<ApplicationDriverFormVM, ApplicationDriverDomain>()
.ForMember(dest => dest.Addresses, opt => opt.ResolveUsing(GetAddresses));
...
static object GetAddresses(ApplicationDriverFormVM src)
{
var result = Mapper.Map<List<ApplicationDriverAddressDomain>>(src.PreviousAddresses);
foreach(var item in result)
{
item.IsPresentAddress = false;
}
var present = Mapper.Map<ApplicationDriverAddressDomain>(src.PresentAddress);
present.IsPresentAddress = true;
result.Add(present);
return result;
}
来源类:
public class ApplicationDriverFormVM
{
public ApplicationDriverAddressFormVM PresentAddress { get; set; }
public List<ApplicationDriverAddressFormVM> PreviousAddresses { get; set; }
}
public class ApplicationDriverAddressFormVM
{
[Required]
[StringLength(256)]
[Display(Name = "Address")]
public string Address { get; set; }
[Required]
[StringLength(256)]
[Display(Name = "City")]
public string City { get; set; }
//.....
}
目的地类:
public class ApplicationDriverDomain
{
public List<ApplicationDriverAddressDomain> Addresses { get; set; }
}
public class ApplicationDriverAddressDomain
{
public int Id { get; set; }
public string Address { get; set; }
public string City { get; set; }
//....
public bool IsPresentAddress { get; set; }
}
所以,我想将 PresentAddress(一个对象)和 PreviousAddresses(集合)映射到 Addresses 属性(集合),其中每个元素都有 IsPresentAddress 属性,这应该是真的,如果它PreviousAddresses 映射元素被映射为 PresentAddress 和 false。我试着写这样的地图基本规则:
CreateMap<ViewModels.ApplicationDriverFormVM, ApplicationDriverDomain>();
CreateMap<ViewModels.ApplicationDriverAddressFormVM, ApplicationDriverAddressDomain>();
当然,它不能正常工作。怎么做到的?
这可以通过 ForMember
扩展方法来完成。
这是一种快速而肮脏的方式来获得你想要的东西。它创建了一个新的 ApplicationDriverAddressFormVM
组合列表来映射,但如果您浏览文档,您可能会找到更优雅的内容。
Mapper.CreateMap<ApplicationDriverFormVM, ApplicationDriverDomain>()
.ForMember(dest => dest.Addresses, opt => opt.MapFrom(src => src.PreviousAddresses.Union(new List<ApplicationDriverAddressFormVM>() { src.PresentAddress })));
Mapper.CreateMap<ApplicationDriverAddressFormVM, ApplicationDriverAddressDomain>();
经过进一步调查,我发现了以下方法。它使用 ResolveUsing
选项。同样,这很粗糙,只使用了我发现的第一个功能。您应该进一步探索 IMemberConfigurationExpression
界面,看看还有哪些其他选项
Mapper.CreateMap<ApplicationDriverFormVM, ApplicationDriverDomain>()
.ForMember(dest => dest.Addresses, opt => opt.ResolveUsing(GetAddresses));
...
static object GetAddresses(ApplicationDriverFormVM src)
{
var result = Mapper.Map<List<ApplicationDriverAddressDomain>>(src.PreviousAddresses);
foreach(var item in result)
{
item.IsPresentAddress = false;
}
var present = Mapper.Map<ApplicationDriverAddressDomain>(src.PresentAddress);
present.IsPresentAddress = true;
result.Add(present);
return result;
}