如何在 automapper 中为 aftermap 上的目标属性赋值

Posted

技术标签:

【中文标题】如何在 automapper 中为 aftermap 上的目标属性赋值【英文标题】:How to assign value to destination property on aftermap in automapper 【发布时间】:2020-10-21 18:42:05 【问题描述】:

我有这些课程

public class Student

    public int StudentId  get; set; 
    public int Name  get; set; 
    public string SubjectIds  get; set;  //Comma delimited string of subject ID
    public string Grades  get; set;  //Comma delimited string of subject ID



public class StudentListItemDto

    public int StudentId  get; set; 
    public int StudentName  get; set; 
    public IEnumerable<SubjectGradeDto> Tags  get; set; 


public class SubjectGradeDto 

    public int SubjectId  get; set; 
    public string Grade  get; set; 

在我的映射配置文件中,我将IEnumerable&lt;Student&gt; 映射到List&lt;StudentListItemDto&gt;

CreateMap<IEnumerable<Student>, List<StudentListItemDto>>()
        .AfterMap((src, dest) =>
            
                List<StudentListItemDto> iStudentListItemDto;
                iStudentListItemDto= src.Select(p =>
                  new StudentListItemDto
                  
                      StudentId= p.StudentId,
                      StudentName= p.Name,
                      Tags = p.SubjectIds!= null ? p.SubjectIds.Split(",").Select((tag, i) => new SubjectGradeDto  SubjectIds= int.Parse(tag), Grade= p.Grades.Split(",")[i] ) : null
                  ).ToList();
                dest = iStudentListItemDto; // I'm assigning values to destination
            );

我以这种方式映射它的原因是因为我需要将 Student 类的 Subjects 和 Grades 属性映射到 IEnumerable&lt;SubjectGradeDto&gt; 的逗号分隔值

我们将不胜感激进一步改进映射。

但我的问题是我在分配时

dest = iStudentListItemDto;

在 AfterMap 中。当我调试它时,它有一个值,但是当映射在这里执行时

IEnumerable<StudentListItemDto> iStudentListItemDto= new List<StudentListItemDto>();
        iStudentListItemDto = _mapper.Map<IEnumerable<Student>, IEnumerable<StudentListItemDto>>(searchResult, iStudentListItemDto);

搜索结果为IEnumerable&lt;Student&gt;

iStudentListItemDto 计算结果为空列表。

问题是为什么?

【问题讨论】:

【参考方案1】:

在您的 CreateMap 中,您的映射 IEnumerableList 并且在有效映射时,您正在从 IEnumerable 映射到 IEnumerable

List 是 IEnumerable,但 IEnumerable 基本上不是 List。

使用您创建的此映射,您只有从 IEnumerable 到 List 的方向。

一个更好的方法,我可以看到你只使用这种方式来映射标签,是做这样的事情

CreateMap<Student, StudentListItemDto>()
        .ForMember(dto => dto.StudentName, opt => opt.MapFrom(s => s.Name))
        .ForMember(dto => dto.Tags, opt => opt.Ignore())
        .AfterMap((student, dto) =>
            
                dto.Tags = student.SubjectIds!= null ? student.SubjectIds.Split(",").Select((tag, i) => new SubjectGradeDto  SubjectIds= int.Parse(tag), Grade= student.Grades.Split(",")[i] ) : null;
            );

现在,如果 AutoMapper 发现您正在映射单个对象或这些对象的列表,它将正确映射此列表中的每个对象。

这是因为您没有使用整个列表来创建此标签列表。

【讨论】:

我如何获得 p.SubjectIds。 VS 不识别 p 对不起,我的错。呵呵。 p 应该是您要映射的学生。我只是将名称从src/dest 更改为student/dto,以便更明显地映射方向。 :)

以上是关于如何在 automapper 中为 aftermap 上的目标属性赋值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 .NetCore 中使用 AutoMapper 高级功能

如何调试到 AutoMapper 代码?

如何在 AutoMapper 中映射通用结构类型

如何在 Automapper 中映射匿名对象

Automapper - 如何重用对象而不是创建新对象(此对象在列表中)

如何在 C# 中使用 AutoMapper