0
votes

I've set my mapping up as follows:

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

Where I'm mapping from a List in my SourceClass to a string in my destination class.

My question is, how can I handle the case where "Providers" is null?

I've tried using:

src?.Providers?.FirstOrDefault()

but I get an error saying I can't use null propagators in a lambda.

I've been reading up on Automapper and am still unsure if AM automatically handles the null case or not. I tried to build the expression tree, but was not able to see any information that provided additional informations.

If it helps, I'm using automapper v 6.1.1.

2
Surely you can write some unit tests to see what happens. - Lucian Bargaoanu
@LucianBargaoanu you're right, I will do that now - blazerix
Not able to test this right now, but you could try src?.Providers?.FirstOrDefault() ?? "". This sets the value to an empty string if the expression proceeding ?? evaluates to null. - Tyler Hundley
@TylerHundley So I added a unit test, and if Providers is null, it maps to null. Do you know how I'd be able to map an empty list to an empty list? As of now, I believe it is mapping an empty list to null (because of FirstOrDefault) - blazerix
Do you mean map an empty list to an empty string? A null list to an empty string? Have you tried the code in my previous comment? - Tyler Hundley

2 Answers

1
votes

Try to use NullSubstitution option from AutoMapper you can read here

1
votes

You could try using a ValueConverter with AutoMapper. That might look something like this

public class ListFormatter : IValueConverter<string, List<string>>
{
  public List<string> Convert(string source)
  {
    if (source != null)
    {
      return new List<string> { source };
    }
    return new List<string>();
  }
}

And then you can use it like this

CreateMap<SourceClass, DestinationClass>()
  .ForMember(destinationMember => destinationMember.Provider,
             memberOptions => memberOptions.ConvertUsing(new ListFormatter()));

This would allow you to change your value converter in the future if you need to switch logic or do something more complex.

Edit

Since you are using an older version, you could use a private/static/extension method to do the same thing. So something like

List<string> ConvertStringToList(string source)
{
  if (source != null)
  {
    return new List<string> { source };
  }
  return new List<string>();
}

and then call it like so

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

I generally prefer this to doing something inline as things get more complex, for the sake of readability