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

How to assign value to destination property on aftermap in automapper

我有这些 classes

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<Student> 映射到 List<StudentListItemDto>:

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

我之所以这样映射是因为我需要映射学生 class 的科目和成绩 属性,这是 IEnumerable<SubjectGradeDto>[= 的逗号分隔值20=]

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

但是我的问题是我在赋值的时候

dest = iStudentListItemDto;

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

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

其中搜索结果为 IEnumerable<Student>

iStudentListItemDto 评估为空列表。

问题是为什么?

在您的 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 发现您正在映射单个对象或这些对象的列表,它将正确映射此列表中的每个对象。

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