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);
}
用例
假设您要将数据从视图模型映射到域模型。视图模型仅包含域模型中的一些项目,以便 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);
}