Offir
Offir

Reputation: 3491

Automapper - conditional mapping on destination

Mapping:

   .ForMember(dest => dest.DisplayName, opt =>
                {
                    opt.PreCondition(location => location.Parent != null);
                    opt.MapFrom(src => src.Name + ", " + src.Parent.Name);
                })
                .ForMember(dest => dest.DisplayName, opt =>
                {
                    opt.PreCondition((src, dest, context) => dest.DisplayName == null);
                    opt.MapFrom(src => src.Name);
                })

Expected result:
If the first condition is met don't override the mapping.

What actually happens:
The second mapping is overriding the first mapping.

How can I solve this?

Upvotes: 1

Views: 2368

Answers (2)

Prolog
Prolog

Reputation: 3354

It doesn't work because you are overwriting previous mapping expressions calling another ForMember() for the same member, which is your case is DisplayName. Consider such case:

.ForMember(d => d.DisplayName, o => o.MapFrom(s => "1"))
.ForMember(d => d.DisplayName, o => o.MapFrom(s => "2"))
.ForMember(d => d.DisplayName, o => o.MapFrom(s => "3"));

Which value will be mapped to DisplayName?

3

So in your case, your first conditional mapping expression is overwriten by the second one. To make it work, join the conditional mapping into one mapping expression:

.ForMember(
    dest => dest.DisplayName,
    opts => opts.MapFrom((src, dest) =>
    {
        if (src.Parent != null)
        {
            return string.Join(", ", src.Name, src.Parent.Name);
        }
        else
        {
            if (dest.DisplayName is null)
            {
                return src.Name;
            }
            else
            {
                return "Some other value when no conditions were met.";
            }
        }
    }));

Upvotes: 3

colinD
colinD

Reputation: 2039

It would be a cool feature to have but I don't see it anywhere in Automapper documentation.

This should however work in your case if the logic is not more complex.

   .ForMember(dest => dest.DisplayName, opt =>
   {
       opt.MapFrom(src => src.Name + (location.Parent != null ? ", " + src.Parent.Name : null));
   })

Upvotes: 1

Related Questions