Search code examples
c#enumsautomappernullable

AutoMapper maps to Enum default value instead of skipping if null


I'm using automapper to update properties of an object; "merging" two objects but only if the source member is != null. (According to this question)

Apparently it does not work with Enums. After calling MergeObject method, it maps to the enum default's value (Pendente) instead of ignoring it and leaving destination as it is.

It works fine for nullable int, for exemple.

When debugging, if I set a breakpoint on the condition (=> member != null), it'll show member = Pendente, even when Source.Situacao is null.

enter image description here

Hitting F10 goes to the next member but you can see that it changed destination.Situacao value.

enter image description here

It seems like a bug to me, but my issue was closed. Any thoughts?

public class FooViewModel
{
    public Guid Id { get; set; }
    public Status? Situacao { get; set; }
}

public class FooModel
{
    public Guid Id { get; set; }
    public Status Situacao { get; set; }
}

public enum Status
{
    Pendente,
    EmProcessamento,
    Processada
}

private static void Initialize()
{
    Mapper.Initialize(cfg =>
    {
        cfg.CreateMap<FooViewModel, FooModel>()
          .ForAllMembers(o => o.Condition((source, destination, member) => member != null));
    });
}

public static void MergeObject(FooViewModel source, FooModel destination)
{
    Mapper.Map(source, destination);
}

EDIT1: My goal is to achieve basically the functionality described in here but I can't see the property IsSourceValueNull.

EDIT2: I managed to achieve my goal using the following line but I had to specify the member explicitly. Is there a generic way to apply this to all members?

cfg.CreateMap<FooViewModel, Foo>()
                    .ForMember(dest => dest.Situacao, opt => opt.MapFrom((source, dest) =>  source.Situacao ?? dest.Situacao));

Solution

  • Ended up using the solution in my second edit, thanks everyone for the input.

    cfg.CreateMap<FooViewModel, Foo>()
                    .ForMember(dest => dest.Situacao, opt => opt.MapFrom((source, dest) =>  source.Situacao ?? dest.Situacao));