使用AutoMapper将成员映射委托给子对象 [英] delegating Member mapping to child object with AutoMapper
问题描述
我有一个目标类,它结合了源类和该源类的内部类的属性.
class Source {
public int Id {get;set;}
public int UseThisInt {get;set;}
public InnerType Inner {get;set;}
// other properties that the Destination class is not interested in
}
class InnerType {
public int Id {get;set;}
public int Height {get;set;}
// more inner properties
}
我的目标类应结合UseThisInt
和InnerType
的所有属性.
class Destination {
public int Id {get;set;}
public int UseThisInt {get;set;}
public int Height {get;set;}
// more inner properties that should map to InnerType
}
现在,我的AutoMapper配置如下:
CreatMap<Source, Destination>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Inner.Id))
.ForMember(d => d.Height, o => o.MapFrom(s => s.Inner.Height));
AutoMapper可以正确地在Source
和Destination
之间映射UseThisInt
,但是我希望能够在没有显式ForMember
配置的情况下使其映射Destination中的所有其他属性,例如Height
.>
我尝试使用
Mapper.Initialize(cfg => cfg.CreateMap<Source, Destination>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Inner.Id))
.ForMember(d => d.UseThisInt, o => o.MapFrom(s => s.UseThisInt))
.ForAllOtherMembers(o => o.MapFrom(source=> source.Inner))
);
,但是没有达到预期的效果,并且保持Destination.Height
不变.
AutoMapper的大多数示例演示了如何从某些源对象创建新的Destination对象,但是AutoMapper也可以用于 update :现有对象从源对象获取那些已映射的属性,而其余所有属性保持不变.
因此,可以分多个步骤从源映射到目标.
因此,如果您像这样从InnerType
创建映射配置:-
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Destination>();
cfg.CreateMap<InnerType, Destination>();
});
然后,您可以利用此功能通过两次映射到目标对象来覆盖映射.
var dest = Mapper.Map<Destination>(src);
Mapper.Map(src.Inner, dest);
此方法的一个缺点是,在使用Mapper生成Destination对象时,您需要注意这一点.但是,您可以选择将AfterMap
指令.
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Destination>()
.AfterMap((src, dest) => Mapper.Map(src.Inner, dest));
cfg.CreateMap<InnerType, Destination>();
});
使用此更新的配置,您可以通过一个Map调用执行映射:-
var dest = Mapper.Map<Destination>(src);
I have a destination class that combines properties from a source class and an inner class of that source class.
class Source {
public int Id {get;set;}
public int UseThisInt {get;set;}
public InnerType Inner {get;set;}
// other properties that the Destination class is not interested in
}
class InnerType {
public int Id {get;set;}
public int Height {get;set;}
// more inner properties
}
my destination class should combine UseThisInt
and all properties of the InnerType
.
class Destination {
public int Id {get;set;}
public int UseThisInt {get;set;}
public int Height {get;set;}
// more inner properties that should map to InnerType
}
Now my AutoMapper configuration looks like this:
CreatMap<Source, Destination>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Inner.Id))
.ForMember(d => d.Height, o => o.MapFrom(s => s.Inner.Height));
AutoMapper will correctly map UseThisInt
between Source
and Destination
, but I would like to be able to let it map all the other properties in Destination like Height
without an explicit ForMember
configuration.
I tried using
Mapper.Initialize(cfg => cfg.CreateMap<Source, Destination>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Inner.Id))
.ForMember(d => d.UseThisInt, o => o.MapFrom(s => s.UseThisInt))
.ForAllOtherMembers(o => o.MapFrom(source=> source.Inner))
);
, but that did not achieve the intended result and left Destination.Height
untouched.
Most examples of AutoMapper demonstrate creating a new Destination object from some source object, but AutoMapper can also be used to update an existing object taking those properties from the source object that are mapped and leaving any remaining properties untouched.
Consequently it is possible to map from the source to the destination in multiple steps.
So if you create a mapping configuration from InnerType
like so:-
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Destination>();
cfg.CreateMap<InnerType, Destination>();
});
Then you can make use of this ability to overlay mappings by mapping into the destination object twice.
var dest = Mapper.Map<Destination>(src);
Mapper.Map(src.Inner, dest);
One downside to this approach is that you need to be mindful of this when using the Mapper to generate a Destination object. However, you have the option of declaring this second mapping step within your AutoMapper configuration as an AfterMap
instruction.
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Destination>()
.AfterMap((src, dest) => Mapper.Map(src.Inner, dest));
cfg.CreateMap<InnerType, Destination>();
});
With this updated configuration you can perform the mapping with a single Map call:-
var dest = Mapper.Map<Destination>(src);
这篇关于使用AutoMapper将成员映射委托给子对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!