1

I have the following Company and its nested object CompanyEmployee:

public class Company
{ 
    public string Id { get; set; }
    public string LogoPath { get; set; }
    public string RammeId { get; set; }
    public List<CompanyEmployee> Employees { get; set; }
}

public class CompanyEmployee
{
    public string Id { get; set; }
    [ForeignKey("Company")]
    public string CompanyId { get; set; }
    public Company Company { get; set; }
    public string EmployeeId { get; set; }
}

Now I want to map the Entities to Dtos defined as the following objects CompanyDto and its nested object EmployeeDto:

public class CompanyDto
{
    [Required]
    public string Id { get; set; }
    [Required]
    public string Name { get; set; }
    public string LogoPath { get; set; }
    public string RammeId { get; set; }
    public IFormFile FormFile { get; set; }
    public List<EmployeeDto> Employees { get; set; }
}   

public class EmployeeDto
{
    public string Id { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
    public string PhoneNumber { get; set; }
    public List<RoleDto> Roles { get; set; }
} 

My problem is the CompanyEmployee to EmployeeDto mapping.

How can I create a map that can take the property EmployeeId and map it to the Id property of EmployeeDto?

Currently, I have the following maps:

    CreateMap<EmployeeDto, CompanyEmployee>(MemberList.Destination)
        .ForMember(emp => emp.EmployeeId, opt => opt.MapFrom(ce => ce.Id));

    CreateMap<CompanyDto, Company>(MemberList.Destination)
        .ForMember(c => c.Employees.Select(e => e.CompanyId), opt => opt.MapFrom(cd => cd.Id));

    CreateMap<Company, CompanyDto>(MemberList.Destination)
        .ForMember(c => c.Id, opt => opt.MapFrom(cd => cd.Employees.First().CompanyId));

2 Answers 2

1

You want to create an AutoMapper Profile to configure each property mapping. Create classes that inherit from Profile and put the configuration in the constructor.

For example:

public class EmployeeProfile : Profile
    {
        //Constructor
        public EmployeeProfile()
        {
            //Mapping properties from CompanyEmployee to EmployeeDto
            CreateMap<CompanyEmployee, EmployeeDto>()
            .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.EmployeeId));

            //Mapping properties from EmployeeDto to CompanyEmployee 
            CreateMap<EmployeeDto, CompanyEmployee>()
            .ForMember(dest => dest.EmployeeId, opt => opt.MapFrom(src => src.Id));
        }
    }
    public class CompanyProfile : Profile
    {
        //Constructor
        public CompanyProfile()
        {
            //Mapping properties from Company to CompanyDto
            CreateMap<Company, CompanyDto>()
            .ForMember(dest => dest.Employees, opt => opt.MapFrom(src => src.Employees));

            //Mapping properties from CompanyDto to Company 
            CreateMap<CompanyDto, Company>()
            .ForMember(dest => dest.Employees, opt => opt.MapFrom(src => src.Employees))
            //Setting CompanyId
            .AfterMap((src, dest) => {
                foreach (var employee in dest.Employees)
                {
                    employee.CompanyId = dest.Id;
                }
            });
        }
    }

AutoMapper Profile Configuration Documentation

Sign up to request clarification or add additional context in comments.

4 Comments

But isnt the mapping from Company to CompanyDto missing the CompanyId on all the Employees?
ReverseMap can reverse that MapFrom so it's needed only on the initial map.
@Anonymous The Employee class you provided has a CompanyId property that should be set when you retrieve the entity it from the Database. The EmployeeDto class you provided does not has a CompanyId property so you only need to set the CompanyId going from CompanyDto to Company, which happens on the AfterMap call.
@elite_developer You are correct. Thanks for the explanation and answer
1

Just create Profile and all properties which have the same name will mapped automatically. However, properties which do not have the same names, they should have custom mapping:

public class FromModelToDto : Profile
{
    public FromModelToDto ()
    {
        CreateMap<CompanyEmployee, EmployeeDto>()
            .ForMember(dest.Id, opts => opts.MapFrom(model => model.EmployeeId))
    }
}

UPDATE:

If you want to map from Dto to Model, then you should create another mapping class:

public class FromDtoToModel : Profile
{
    public FromDtoToModel ()
    {
        CreateMap<EmployeeDto, CompanyEmployee>()
            .ForMember(dest.EmployeeId, opts => opts.MapFrom(model => model.Id))
    }
}

You can read more about Automapper here.

6 Comments

Alright, so I should rename the Id property of EmployeeDto?
Ok thanks. But what about the reverse map? I don't see how I can map the CompanyDto Id to the ForeignKey CompanyId in CompanyEmployee?
@Anonymous If your properties is not mapped, then you should write custom mapping
Please see updated question. Would that also work for the property Id in CompanyDto and the property CompanyId in List<CompanyEmployee>?
@Anonymous I don't have a chance to test it, however as far as I remember it should work. Just try to do it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.