Automapper:防止在未声明源成员时用 null 覆盖目标成员

Automapper : Prevent overwriting of destination member with null when source member is undeclared

用例

假设您要将数据从视图模型映射到域模型。视图模型仅包含域模型中的一些项目,以便 POST 和更新部分视图,而不是整个视图。

class ViewModel {
     public Guid id { get; set; }
     public string name { get; set; }
     public string address { get; set;}
}

class DomainModel {
     public Guid id { get; set; }
     public string name { get; set; }
     public string address { get; set; }
     public string houseColor { get; set; }
     public virtual Vehicle car { get; set; }
}

目前,当ViewModel映射到DomainModel时,name和address会被正确设置,但是houseColor和car会被null覆盖。

我尝试使用以下映射但没有效果。映射数据后,houseColor 和 car 被无意中覆盖为 null :

var map1 = new MapperConfiguration(
     cfg =>cfg.CreateMap<ViewModel,DomainModel>()
          .ForAllMembers(o =>o.Condition(src =>src != null))
);

var map2 = new MapperConfiguration(
     cfg =>cfg.CreateMap<ViewModel,DomainModel>()
          .ForMember(dest =>dest.houseColor, o =>o.Ignore() )
          .ForMember(dest =>dest.car, o =>o.Ignore() )
);

var map3 = new MapperConfiguration(
     cfg =>cfg.CreateMap<ViewModel,DomainModel>()
          .ForMember(dest =>dest.houseColor, o =>o.UseDestinationValue() )
          .ForMember(dest =>dest.car, o =>o.UseDestinationValue() )
);

var map4 = new MapperConfiguration(
     cfg =>cfg.CreateMap<ViewModel,DomainModel>()
          .ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null))
);

控制器

[HttpPost]
public PartialViewResult _Partial_View(ViewModel VM) {
     var DomainModel = db.DomainModels.Find(VM.Id);

     //calculations to update VM data.
     //Creation of mappings as detailed above.
     
     var mapper = mapName.CreateMapper();
     DomainModel = mapper.Map<ViewModel,DomainModel>(VM);
     db.SaveChanges();
     return PartialView("PartialView.cshtml",VM);
}

当等效的源值未声明时,有什么方法可以防止 AutoMapper 用 null 覆盖域模型值?

备选方案

可以简单地从领域模型中取出值,将它们存储在变量中,映射后将它们放回领域模型中,但这很容易变得难以维护,并且违背了使用映射器的目的。

补充说明

Stack Overflow post 试图解决这个问题,但是 post 是 2014 年 9 月的,并且使用了过时的 AutoMapper 版本,导致答案无效。 AutoMapper can't prevent null source values if not all source properties match and

这行得通吗?

[HttpPost]
public PartialViewResult _Partial_View(ViewModel VM) {
     var DomainModel = db.DomainModels.Find(VM.Id);

     //calculations to update VM data.
     //Creation of mappings as detailed above.

     var mapper = mapName.CreateMapper();
     mapper.Map<ViewModel,DomainModel>(VM, DomainModel);
     db.SaveChanges();
     return PartialView("PartialView.cshtml",VM);
}