【问题标题】:Automapper map nested different object propertiesAutomapper 映射嵌套不同的对象属性
【发布时间】:2020-02-12 08:34:40
【问题描述】:

我有以下Company 及其嵌套对象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; }
}

现在我想将实体映射到定义为以下对象CompanyDto及其嵌套对象EmployeeDto的Dtos:

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; }
} 

我的问题是 CompanyEmployeeEmployeeDto 的映射。

如何创建可以获取属性EmployeeId 并将其映射到EmployeeDtoId 属性的映射?

目前,我有以下地图:

    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));

【问题讨论】:

    标签: c# .net .net-core automapper


    【解决方案1】:

    您想创建一个 AutoMapper 配置文件来配置每个属性映射。 创建继承自 Profile 的类,并将配置放入构造函数中。

    例如:

    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

    【讨论】:

    • 但是从 Company 到 CompanyD 的映射不是缺少所有员工的 CompanyId 吗?
    • ReverseMap 可以反转 MapFrom 所以它只需要在初始地图上。
    • @Anonymous 您提供的 Employee 类有一个 CompanyId 属性,当您从数据库中检索实体时应该设置该属性。您提供的 EmployeeDto 类没有 CompanyId 属性,因此您只需设置 CompanyId 从 CompanyDto 到 Company,这发生在 AfterMap 调用中。
    • @elite_developer 你是对的。感谢您的解释和回答
    【解决方案2】:

    只需创建Profile,所有具有相同名称的属性都会自动映射。但是,名称不同的属性,它们应该具有自定义映射:

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

    更新:

    如果你想从 Dto 映射到 Model,那么你应该创建另一个映射类:

    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.

    【讨论】:

    • 好的,我应该重命名EmployeeDto的Id属性?
    • 好的,谢谢。但是反向地图呢?我看不到如何将 CompanyDto Id 映射到 CompanyEmployee 中的 ForeignKey CompanyId?
    • @Anonymous 如果你的属性没有被映射,那么你应该编写自定义映射
    • 请查看更新后的问题。这也适用于 CompanyDto 中的属性 Id 和 List 中的属性 CompanyId 吗?
    • @Anonymous 我没有机会测试它,但据我记得它应该可以工作。试着去做吧。
    猜你喜欢
    • 1970-01-01
    • 2017-07-20
    • 2012-07-19
    • 1970-01-01
    • 2016-03-20
    • 2020-04-03
    • 2022-01-06
    • 1970-01-01
    • 2012-02-25
    相关资源
    最近更新 更多