Overwrite Existing Mapping with Automapper

4.6k Views Asked by At

I have the following entity & view model:

public class Report
{
    public int? Day { get; set; }

    public int? Week { get; set; }

    public int? Month { get; set; }

    public int Year { get; set; }
}

public class ReportViewModel
{
    public int Value { get; set; }

    public int Year { get; set; }
}

To map this I am currently using the following.

Mapper.Initialize(c =>
        {
            c.CreateMap<Report, ReportViewModel>();
        }

Then select using .Project.To<>

var models = Context.Project().To<ReportViewModel>().ToList();

My issue is I am passing the enum to this query that tells me whether value needs to be Month, Week, or Day.

public enum ReportingPeriod
{
    None = 0,
    Monthly = 1,
    Weekly = 2,
    Daily = 4
}

How do I set the mapping of the Value property to be dynamic based on the enum passed?

I tried overwriting the configuration before the query executed with the following, but this did not work.

Mapper.CreateMap<Report, ReportViewModel>()
                    .ForMember(src => src.Value, dest => dest.MapFrom(r => (reportingPeriod == ReportingPeriod.Monthly) ? 
                                                                                                                r.Month.Value : reportingPeriod == ReportingPeriod.Weekly ?
                                                                                                                                            r.Week.Value : r.Day.Value));
2

There are 2 best solutions below

0
On BEST ANSWER

using Automapper version 5.2.0, your syntax should be as below. You should use ResolveUsing instead of MapFrom and swith-case should be within curly brackets. you dont have to use any Mapper.Initialize(). I tested this code and it works for me. I hope that it helps for you also. Cheers.

Similar question asked here. see the answer from Mrchief

   var config = new MapperConfiguration(cfg =>
                    {
        Mapper.CreateMap<Report, ReportViewModel>()
            .ForMember(src => src.Value, 
                       dest => dest.ResolveUsing(r => {
                            switch(reportingPeriod)
                            {
                                case ReportingPeriod.Daily:
                                    return r.Day.Value;
                                    break;
                                case ReportingPeriod.Weekly:
                                    return r.Week.Value;
                                    break;
                                case ReportingPeriod.Monthly:
                                    return r.Month.Value;
                                    break;
                                case default:
                                    //None
                                    return null;
                                    break;
                               }
                            }));
            });

       var mapper = config.CreateMapper();
8
On

You need to return the value. IMO a switch statement is clearer than nested if else:

Mapper.CreateMap<Report, ReportViewModel>()
    .ForMember(src => src.Value, 
               dest => dest.MapFrom(r => 
                    switch(reportingPeriod)
                    {
                        case ReportingPeriod.Daily:
                            return r.Day.Value;
                            break;
                        case ReportingPeriod.Weekly:
                            return r.Week.Value;
                            break;
                        case ReportingPeriod.Monthly:
                            return r.Month.Value;
                            break;
                        case default:
                            //None
                            return null;
                            break;
                    }));