[SOLVED] AutoMapper – Map source object to nested object

Issue

How to map a single object to a nested object?

The below one is my entity.

class Employee
{
    public string name { get; set; }
    public string city_name { get; set; }
    public string State_name { get; set; }
}

I want to map to

class Employee
{
    public string Name;
    public Location Location;
}

class Location
{
    public string City;

    public string State;
}

Please note that the property names are different. Can anyone help to map these using AutoMapper?

Solution

Solution 1: ForPath

1.1 Create Profile instance with inheriting from Profile and put the configuration in the constructor.

1.1.1 Using ForPath to map nested property.

public class EmployeeProfile : Profile
{
    public EmployeeProfile()
    {
        CreateMap<Employee, EmployeeDto>()
            .ForPath(dest => dest.Location.City, opt => opt.MapFrom(src => src.city_name))
            .ForPath(dest => dest.Location.State, opt => opt.MapFrom(src => src.State_name));
    }
}

1.2 Adding profile to mapper configuration

public static void Main()
{
    var config = new MapperConfiguration(cfg =>
    {

        cfg.AddProfile<EmployeeProfile>();

        // Note: Demo program to use this configuration rather with EmployeeProfile
        /*
        cfg.CreateMap<Employee, EmployeeDto>()
            .ForPath(dest => dest.Location.City, opt => opt.MapFrom(src => src.city_name))
            .ForPath(dest => dest.Location.State, opt => opt.MapFrom(src => src.State_name));
        */      
    });
    IMapper mapper = config.CreateMapper();
        
    var employee = new Employee{name = "Mark", city_name = "City A", State_name = "State A"};

    var employeeDto = mapper.Map<Employee, EmployeeDto>(employee);
}

Sample Solution 1 on .Net Fiddle


Solution 2: AfterMap

2.1 Create Profile instance with inheriting from Profile and put the configuration in the constructor.

2.1.1 Using AfterMap to perform mapping nested property after map occurs.

public class EmployeeProfile : Profile
{
    public EmployeeProfile()
    {
        CreateMap<Employee, EmployeeDto>()
            .AfterMap((src, dest) => { dest.Location = 
                    new Location {
                        City = src.city_name,
                        State = src.State_name
                    };
                });
    }
}

2.2 Adding profile to mapper configuration

public static void Main()
{
    var config = new MapperConfiguration(cfg =>
    {

        cfg.AddProfile<EmployeeProfile>();

        // Note: Demo program to use this configuration rather with EmployeeProfile
        /*
        cfg.CreateMap<Employee, EmployeeDto>()
            .AfterMap((src, dest) => { dest.Location = 
                    new Location {
                        City = src.city_name,
                        State = src.State_name
                    };
                });
        */      
    });
    IMapper mapper = config.CreateMapper();
        
    var employee = new Employee{name = "Mark", city_name = "City A", State_name = "State A"};

    var employeeDto = mapper.Map<Employee, EmployeeDto>(employee);
}

Sample Solution 2 on .Net Fiddle


References

  1. ForPath
  2. Profile Instances
  3. Before and After Map

Answered By – Yong Shun

Answer Checked By – Willingham (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *