Automapper - сопоставить свойство с коллекцией
Исходные классы:
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 (collection) со свойством Addresses (collection), где каждый элемент имеет свойство IsPresentAddress, которое должно быть истинным, если он был сопоставлен PresentAddress, и false для сопоставленных элементов PreviousAddresses. Я пытаюсь написать такую карту основных правил:
CreateMap<ViewModels.ApplicationDriverFormVM, ApplicationDriverDomain>();
CreateMap<ViewModels.ApplicationDriverAddressFormVM, ApplicationDriverAddressDomain>();
конечно, это не работает должным образом. Как к этому относиться?
1 ответ
Это можно сделать с помощью 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;
}