简体   繁体   中英

AutoMapper - subObject stay null when mapping back to DTO from ViewModel

I have this map:

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<Sistema.DataEntities.Models.Cliente, CadastroModule.Model.Cliente>().ReverseMap();
});

CadastroModule.Model.Cliente (MVVM MODEL):

public class Cliente
{
    public int ClienteID { get; set; }
    public string Nome { get; set; }
    public string EnderecoCEP { get; set;}
    public string EnderecoBairro { get; set; }
    public string EnderecoLogradouro { get; set; }
    public int EnderecoNumero { get; set; }
    public string EnderecoComplemento { get; set; }
}

Sistema.DataEntities.Models (POCO):

public class Cliente : Entity
{
    public Cliente()
    {
        Endereco = new Endereco();
    }

    public int ClienteID { get; set; }

    public string Nome { get; set; }

    public Endereco Endereco { get; set; }//1 pra 1 (Complex type EF)
}

Sistema.DataEntities.Models (POCO):

public class Endereco : Entity
{
    public string CEP { get; set; }
    public string Bairro { get; set; }
    public string Logradouro { get; set; }
    public int Numero { get; set; }
    public string Complemento { get; set; }

}

When i try this its run perfectly:

var t = _clienteService.ClienteService_GetAll().Project().To<Cliente>();

But when i need to back to poco i get trouble:

Sistema.DataEntities.Models.Cliente clifinal = Mapper.Map<Cliente, Sistema.DataEntities.Models.Cliente>(ObCliente);

My result:

在此处输入图片说明

Why the Endereco object is with null values?

Automapper isn't built as much for "unflattening" objects. Your Model --> ViewModel mapping works by convention; the "Endereco" prefix in the destination tells AutoMapper to look in a nested object.

To get this to work the other way, you'll have to add a mapping manually from CadastroModule.Model.Cliente to Sistema.DataEntities.Models.Endereco and then use that mapping in the reverse mapping from CadastroModule.Model.Cliente to Sistema.DataEntities.Models.Cliente :

cfg.CreateMap<Cliente, CadastroModule.Model.Cliente>()
    .ReverseMap()
    // Map the `Endereco` property from `Cliente`
    .ForMember(dest => dest.Endereco, opt => opt.MapFrom(src => src));

cfg.CreateMap<CadastroModule.Model.Cliente, Endereco>();
    .ForMember(dest => dest.Bairro, opt => opt.MapFrom(src => src.EnderecoBairro))
    .ForMember(dest => dest.CEP, opt => opt.MapFrom(src => src.EnderecoCEP))
    .ForMember(dest => dest.Complemento, opt => opt.MapFrom(src => src.EnderecoComplemento))
    .ForMember(dest => dest.Logradouro, opt => opt.MapFrom(src => src.EnderecoLogradouro))
    .ForMember(dest => dest.Numero, opt => opt.MapFrom(src => src.EnderecoNumero));

Rather than map every property of Endereco , you could register Endereco as a source prefix instead:

cfg.CreateMap<Cliente, CadastroModule.Model.Cliente>()
    .ReverseMap()
    .ForMember(dest => dest.Endereco, opt => opt.MapFrom(src => src));

cfg.RecognizePrefixes("Endereco");
cfg.CreateMap<CadastroModule.Model.Cliente, Endereco>();

This solution presented, I think the author's post on two way mapping is worth a read. Essentially, AutoMapper was not built to map back onto domain entities. Of course you can use it however you wish, but that might explain why this kind of scenario is not supported out of the box.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM