0
votes

I have the following two classes:

I have two classes

 public class SourceClass
{
    public Guid Id { get; set; }
    public string Provider { get; set; }
}


public class DestinationClass
{
    public Guid Id { get; set; }
    public List<string> Providers { get; set; }
}

I have the following mappings for my automapper

CreateMap<SourceClass, DestinationClass>()
  .ForMember(destinationMember => destinationMember.Providers,
  memberOptions => memberOptions.MapFrom(src => new List<string> {src.Provider ?? ""}));

CreateMap<DestinationClass, SourceClass>().ForMember(SourceClass => SourceClass.Provider,
                memberOptions => memberOptions.MapFrom(src => src.Providers.FirstOrDefault()));

I wrote some unit tests and can confirm the following behaviour:

When Providers in my destination class is null, it maps to null, which is great. However, I'd like to change my mapping so that if Providers is an empty list, it maps to an empty list and similarly, if Provider is null, I'd want it to map to an empty list instead of a list with an empty string.

Does anyone know how I can go about doing this? I've tried this for my mapping from SourceClass to DestinationClass:

CreateMap<SourceClass, DestinationClass>()
      .ForMember(destinationMember => destinationMember.Providers,
memberOptions => memberOptions.MapFrom(src => !string.IsNullOrEmpty(src.Provider) ? new List<string> {src.Provider} : new List<string>()));

but for going the other way, an empty list is mapping to null, instead of an empty list. (I think because of FirstOrDefault() ). Does anyone know how I can work around this?

2
"so that if Providers is an empty list, it maps to an empty list" - This makes no sense, as Providers is a List<String> and Provider is a string. Just to clarify, you want to map it so that Destination.Providers maps to an empty list when Source.Provider is null or empty? - Tyler Hundley
Yes that is correct - blazerix
And you also need to be able to map in the opposite direction as well, where Source.Provider maps to the first element of Destination.Providers if it is not empty, or an empty string if it is? - Tyler Hundley
yes, here is what I've tried for that memberOptions => memberOptions.MapFrom(src => (src.Providers.Count == 0) ? "" : src.Providers.FirstOrDefault())); - blazerix

2 Answers

0
votes

Yep. I think its because its FirstOrDefaults( ) .. why not use the same ternary operator or an if statement to place your conditions for mapping ?

0
votes

Tested this mapping with AutoMapper 6.1.1

var config = new MapperConfiguration(cfg =>
{
  cfg.CreateMap<SourceClass, DestinationClass>()
    .ForMember(dest => dest.Providers, 
    opt => opt.MapFrom(src => string.IsNullOrEmpty(src.Provider) ? new List<string>() 
                                                                 : new List<string> { src.Provider }));

    cfg.CreateMap<DestinationClass, SourceClass>()
      .ForMember(dest => dest.Provider, 
      opt => opt.MapFrom(src => src.Providers == null ? "" 
                                                      : src.Providers.FirstOrDefault() ?? ""));
});

If you really want it "inline" that will work. I still think it'd be easier to read if you moved it out into a method you could call, or if you could upgrade AutoMapper to leverage the built in converter mapping. Hopefully this gives you enough information to start.