1

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:

enter image description here

Why the Endereco object is with null values?

Danilo Breda
  • 1,092
  • 1
  • 15
  • 30

1 Answers1

1

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.

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
  • If its not a good thing for this scenario... you have other tool? I found something about ValueInjecter... its a good way? Have in mind thats a propotype... the better the tool, less worry. – Danilo Breda Aug 22 '14 at 03:28
  • To "protect" your domain, you might just set properties manually. Again, you *can* use AutoMapper for this, it is just not how it was originally designed from what I understand. – Andrew Whitaker Aug 22 '14 at 03:47
  • What i really need is only a convention based mapper... and i think that Value Injecter http://valueinjecter.codeplex.com will be the better for me... its supports unflattening. Thanks for the help. – Danilo Breda Aug 22 '14 at 04:58