Search code examples
c#enumsautomapperprojectionautomapper-5

Using enums as criteria in Automapper CreateMap and Projection


Using AutoMapper v6.1

Without having to hard code that value in lieu of the enum ((int)POStatusOptions.Ordered), how can you accomplish this map with Projection:

CreateMap<WorkOrderDetail, WorkOrderDetailsListViewModel>(MemberList.Destination)
.ForMember(vm => vm.QtyOnPOs, opt => opt.MapFrom(entity =>
    entity.Item.PODetails
        .Where(pod => pod.POHeader.StatusId >= (int)POStatusOptions.Ordered)
        .Sum(pod => pod.QtyOrdered)
        )))

My configuration for automapper is using profiles. So I have

My Config Class:

public static class AutoMapperConfiguration
{
    public static void Configure()
    {
        //see https://github.com/AutoMapper/AutoMapper/wiki/Configuration
        //see https://github.com/AutoMapper/AutoMapper/wiki/Configuration-validation 
        Mapper.Initialize(am =>
        {
            am.AddProfile<AutoMapperViewModelProfile>();
            am.AddProfile<AutoMapperViewModelProfileAdmin>();
        });

        //uncomment this during testing to get a list of all errors in the browser when you run any page in otis
        Mapper.AssertConfigurationIsValid();
    }    
}

Which is called in Application_Start() like: AutoMapperConfiguration.Configure();

My profile class:

public class AutoMapperViewModelProfile : Profile
{
    public AutoMapperViewModelProfile()
    {
        CreateMap<WorkOrderDetail, WorkOrderDetailsListViewModel>(MemberList.Destination)
        .ForMember(vm => vm.QtyOnPOs, opt => opt.MapFrom(entity =>
            entity.Item.PODetails
            .Where(pod => pod.POHeader.StatusId >= (int)POStatusOptions.Ordered)
            .Sum(pod => pod.QtyOrdered)
        )))
}

Solution

  • In AutoMapper it's called Parameterization. Please see AutoMapper doc.

    In your case it would be:

    POStatusOption poStatusOption = POStatusOption.Whatever;
    CreateMap<WorkOrderDetail, WorkOrderDetailsListViewModel>(MemberList.Destination)
       .ForMember(
          vm => vm.QtyOnPOs, 
          opt => opt.MapFrom(entity =>
             entity.Item.PODetails
                .Where(pod => pod.POHeader.StatusId >= (int)poStatusOption)
                .Sum(pod => pod.QtyOrdered)
          )
       )
    

    And you need to use it like this:

    dbContext.WorkOrderDetails.ProjectTo<WorkOrderDetailsListViewModel>(Config, new { poStatusOption = POStatusOptions.Ordered });