如何在不使用内联映射或多个 .ForMember 的情况下在自动映射器中映射嵌套对象?
How to map nested object in automapper without using inline mapping or multiple .ForMember?
有一个,非常精确地描述了我想要得到的东西,但他们使用的是内联映射。
Source/destination 类型
public class SrcInner
{
public int A {get;set;} // imagine here 100500 properties
}
public class SrcOuter
{
public int B {get;set;}
public SrcInner C {get;set}
}
public class Dest
{
public int A {get;set;} // so here imagine 100500 same properties, as in SrcInner
public int B {get;set;}
}
映射配置
public static void AddMapper(this IServiceCollection services)
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SrcInner, Dest>();
cfg.CreateMap<SrcOuter, Dest>();
});
var mapper = config.CreateMapper();
services.AddSingleton(mapper);
}
预期行为
A属性和B属性在映射后都被填充了。
实际行为
映射后只填充B属性
重现步骤
public class Foo
{
IMapper Mapper{get;set;}
public Foo(IMapper mapper) // comes through dependency injection
{
Mapper = mapper;
}
public Bar()
{
var test = new SrcOuter()
{
B = 10;
C = new SrcInner()
{
A = 10;
}
}
var testDest = new Dest();
mapper.Map(test, Dest);
}
}
是否有正确的方法来设置配置,以便这样的映射可以工作?
更新
有没有办法将 Dest 映射到 SrcOuter 并填充 SrcInner?
文档描述了如何使用 IncludeMembers
here
来实现
在您的情况下,配置为:
cfg.CreateMap<SrcOuter, Dest>().IncludeMembers(s => s.C);
cfg.CreateMap<SrcInner, Dest>(MemberList.None);
如果您希望这两种方式都有效,最惯用的方法是在目标成员前面加上嵌套的源对象名称,这样展平和取消展平就会自动进行。
例如如果您有以下对象:
public class SrcInner
{
public int A { get; set; }
}
public class SrcOuter
{
public int B { get; set; }
public SrcInner Inner { get; set; }
}
public class Dest
{
public int InnerA { get; set; }
public int B { get; set; }
}
您不需要比以下更多的配置:
cfg.CreateMap<SrcOuter, Dest>().ReverseMap();
我想你需要看看这个:https://docs.automapper.org/en/stable/Projection.html
然后你需要
.ForMember(dest => dest.A, opt => opt.MapFrom(src => src.C.A))
有一个
Source/destination 类型
public class SrcInner
{
public int A {get;set;} // imagine here 100500 properties
}
public class SrcOuter
{
public int B {get;set;}
public SrcInner C {get;set}
}
public class Dest
{
public int A {get;set;} // so here imagine 100500 same properties, as in SrcInner
public int B {get;set;}
}
映射配置
public static void AddMapper(this IServiceCollection services)
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SrcInner, Dest>();
cfg.CreateMap<SrcOuter, Dest>();
});
var mapper = config.CreateMapper();
services.AddSingleton(mapper);
}
预期行为
A属性和B属性在映射后都被填充了。
实际行为
映射后只填充B属性
重现步骤
public class Foo
{
IMapper Mapper{get;set;}
public Foo(IMapper mapper) // comes through dependency injection
{
Mapper = mapper;
}
public Bar()
{
var test = new SrcOuter()
{
B = 10;
C = new SrcInner()
{
A = 10;
}
}
var testDest = new Dest();
mapper.Map(test, Dest);
}
}
是否有正确的方法来设置配置,以便这样的映射可以工作?
更新
有没有办法将 Dest 映射到 SrcOuter 并填充 SrcInner?
文档描述了如何使用 IncludeMembers
here
在您的情况下,配置为:
cfg.CreateMap<SrcOuter, Dest>().IncludeMembers(s => s.C);
cfg.CreateMap<SrcInner, Dest>(MemberList.None);
如果您希望这两种方式都有效,最惯用的方法是在目标成员前面加上嵌套的源对象名称,这样展平和取消展平就会自动进行。
例如如果您有以下对象:
public class SrcInner
{
public int A { get; set; }
}
public class SrcOuter
{
public int B { get; set; }
public SrcInner Inner { get; set; }
}
public class Dest
{
public int InnerA { get; set; }
public int B { get; set; }
}
您不需要比以下更多的配置:
cfg.CreateMap<SrcOuter, Dest>().ReverseMap();
我想你需要看看这个:https://docs.automapper.org/en/stable/Projection.html
然后你需要
.ForMember(dest => dest.A, opt => opt.MapFrom(src => src.C.A))