AutoMapper 中子对象中没有前缀名称的扁平化

Ira*_*chi 5 c# automapper

将这些类视为源:

public class SourceParent
{
    public int X { get; set; }
    public SourceChild1 Child1 { get; set; }
    public SourceChild2 Child2 { get; set; }
}

public class SourceChild1
{
    public int A { get; set; }
    public int B { get; set; }
    public int C { get; set; }
    public int D { get; set; }
}

public class SourceChild2
{
    public int I { get; set; }
    public int J { get; set; }
    public int K { get; set; }
    public int L { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试将源映射到与此类似的目的地:

public class Destination
{
    public int X { get; set; }

    public int A { get; set; }
    public int B { get; set; }
    public int C { get; set; }
    public int D { get; set; }

    public int I { get; set; }
    public int J { get; set; }
    public int K { get; set; }
    public int L { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

好吧,使用这个配置,可以进行映射:

Mapper.CreateMap<SourceParent, Destination>()
    .ForMember(d => d.A, opt => opt.MapFrom(s => s.Child1.A))
    .ForMember(d => d.B, opt => opt.MapFrom(s => s.Child1.B))
    .ForMember(d => d.C, opt => opt.MapFrom(s => s.Child1.C))
    .ForMember(d => d.D, opt => opt.MapFrom(s => s.Child1.D))
    .ForMember(d => d.I, opt => opt.MapFrom(s => s.Child2.I))
    .ForMember(d => d.J, opt => opt.MapFrom(s => s.Child2.J))
    .ForMember(d => d.K, opt => opt.MapFrom(s => s.Child2.K))
    .ForMember(d => d.L, opt => opt.MapFrom(s => s.Child2.L));
Run Code Online (Sandbox Code Playgroud)

除此之外,当子类有很多属性,并且所有属性都与父类同名时,这不是一个干净的方法。

理想情况下,我想告诉 AutoMapper 将 Source.Child1 和 Source.Child2 作为源,并将每个匹配的属性名称映射到目标(而不是指定每个属性);像这样的东西:

Mapper.CreateMap<SourceParent, Destination>()
    .AlsoUseSource(s => s.Child1)
    .AlsoUseSource(s => s.Child2);
Run Code Online (Sandbox Code Playgroud)

And*_*ker 3

您可以使用.ConstructUsing它来完成此任务。这不是世界上看起来最干净的东西,但它会起作用:

\n\n
/* Map each child to the destination */\nMapper.CreateMap<SourceChild1, Destination>();\nMapper.CreateMap<SourceChild2, Destination>();\n\nMapper.CreateMap<SourceParent, Destination>()\n    .ConstructUsing(src =>\n    {\n        /* Map A-D from Child1 */\n        var dest = Mapper.Map<Destination>(src.Child1);\n\n        /* Map I-L from Child2 */\n        Mapper.Map(src.Child2, dest);\n\n        return dest;\n    });\n/* X will be mapped automatically. */\n
Run Code Online (Sandbox Code Playgroud)\n\n

这应该成功映射所有属性。

\n\n

不幸的是,调用.AssertConfigurationIsValid将失败,因为属性I-L不会映射到SourceParent\xe2\x86\x92映射的目标类型上Destination

\n\n

当然,您可以打电话给.Ignore为每个映射编写一个调用,但这会破坏摆脱嵌套映射调用的目的。

\n\n

您的另一个选择是利用这个很棒的答案来忽略每个映射上未映射的属性。

\n