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;
    }
Другие вопросы по тегам