如何在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
中,您的映射 IEnumerable
到 List
并且当有效映射时,您正在从 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 发现您正在映射单个对象或这些对象的列表,它将正确映射此列表中的每个对象。
这是因为您没有使用整个列表来创建此标签列表。
我有这些 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
中,您的映射 IEnumerable
到 List
并且当有效映射时,您正在从 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 发现您正在映射单个对象或这些对象的列表,它将正确映射此列表中的每个对象。
这是因为您没有使用整个列表来创建此标签列表。