使用 Automapper 将一些属性从 TSource 映射到 TDestination 而不会丢失旧的其他 TDestination 对象属性值

Map some properties from TSource to TDestination without losing old other TDestination object properties values using Automapper

我正在开发一个 Asp.Net 核心 项目,目标是 .Net 5Clean架构.

我在 Core layer

中有这个 Entity

考试实体:

public class Exam : IExam
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public DateTime ExamDate { get; set; }

    [Required]
    public TimeSpan ExamTime { get; set; }

    [Required]
    public decimal DurationByHour { get; set; }

    [Required]
    public string GroupId { get; set; }

    [Required]
    public string SchoolSubjectId { get; set; }

    [Required]
    public string ProfId { get; set; }

    public virtual Group                 Group         { get; set; }
    public virtual SchoolSubject         SchoolSubject { get; set; }
    public virtual Prof                  Prof          { get; set; }
    public virtual ICollection<ExamMark> ExamMarks     { get; set; }

    public string   CreatedBy    { get; set; }
    public DateTime CreatedOn    { get; set; }
    public bool     IsEdited     { get; set; }
    public string   LastEditor   { get; set; }
    public DateTime LastEditDate { get; set; }
}

我有这个视图模型(用于编辑)一个 Exam 对象

ExamEditVm 视图 model/DTO:

public class ExamEditVm
{
    public int         Id             { get; set; }
    public DateTime    ExamDate       { get; set; }
    public TimeSpan    ExamTime       { get; set; }
    public decimal     DurationByHour { get; set; }
    public string      GroupId        { get; set; }
    public List<Group> Groups         { get; set; }
}

很好,现在当用户在编辑视图中进行一些编辑并提交结果时,另一个Edit 操作结果HTTPPOST 中将接收编辑作为 ExamEditVm 对象。 此时操作应该 select Exam 谁应该被编辑并且使用 MappingProfile 操作将映射 ExamEditVm 对象到 selected Exam 对象

ExamExamEditVm 之间的映射配置文件:

CreateMap<Exam , ExamEditVm>().ReverseMap();

HttpPost 编辑操作结果:

    public async Task<IActionResult> Edit(ExamEditVm model)
            {
                if (ModelState.IsValid)
                {
                    var exam = await _examRepository.GetByIdAsync( model.Id );
                    exam = _mapper.Map<Exam>( model);
                    exam.WriteEditingAudit( _appUser );
    
                    await _examRepository.UpdateAsync( record : exam );
                    await _uow.CommitAsync();
    
                    return RedirectToAction( nameof( Edit ) , new {model.Id} );
                }
// Some logic
            }

到底是什么问题? 问题出在这一行

exam = _mapper.Map<Exam>( model);

当从 ExamEditVm 映射到 Exam 时,exam 将丢失所有未映射的属性值,因为他得到了另一个对象值。 那么如何从 ExamEditVm 映射到 Exam 并在使用 AutomapperMappingProfile 映射后保持 exam 对象旧的未映射属性值?

希望您能理解这个问题。 所以请为他的问题提供任何解决方案。

通过执行 exam = _mapper.Map<Exam>(model); 你实际上是在创建一个新的 Exam 实例, 只有 ExamEditVm model.

中存在的数据

您想要做的是 apply/map 来自 ExamEditVm model 对象的数据到现有的 Exam exam 对象。
为此,您必须使用 Map 重载传递源对象和目标对象:

_mapper.Map(model, exam);