简体   繁体   English

在AutoMapper中的子对象中展平没有带前缀的名称

[英]Flattening without prefixed names in child object in AutoMapper

Consider these classes as source: 将这些类视为源:

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; }
}

I'm trying to map the source to a destination similar to this: 我正在尝试将源映射到类似于此的目标:

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; }
}

Well, using this configuration, it is possible to do the mapping: 好吧,使用这个配置,可以进行映射:

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));

Except that, when the child class has many properties, all of which having the same name with the parent, this is not a clean way. 除此之外,当子类具有许多属性,所有属性与父级具有相同的名称时,这不是一种干净的方式。

Ideally, I'd like to tell AutoMapper to take Source.Child1 and Source.Child2 as a source too, and map every matching property names to the target (instead of specifying every single property); 理想情况下,我想告诉AutoMapper将Source.Child1和Source.Child2作为源,并将每个匹配的属性名称映射到目标(而不是指定每个属性); something like this: 这样的事情:

Mapper.CreateMap<SourceParent, Destination>()
    .AlsoUseSource(s => s.Child1)
    .AlsoUseSource(s => s.Child2);

You can use .ConstructUsing to accomplish this. 您可以使用.ConstructUsing来完成此任务。 It's not the cleanest looking thing in the world, but it'll work: 它不是世界上最干净的东西,但它会起作用:

/* Map each child to the destination */
Mapper.CreateMap<SourceChild1, Destination>();
Mapper.CreateMap<SourceChild2, Destination>();

Mapper.CreateMap<SourceParent, Destination>()
    .ConstructUsing(src =>
    {
        /* Map A-D from Child1 */
        var dest = Mapper.Map<Destination>(src.Child1);

        /* Map I-L from Child2 */
        Mapper.Map(src.Child2, dest);

        return dest;
    });
/* X will be mapped automatically. */

This should successfully map all of the properties. 这应该成功映射所有属性。

Unfortunately, a call to .AssertConfigurationIsValid will fail, since properties I - L will not be mapped on the destination type for the mapping from SourceParentDestination . 不幸的是,对.AssertConfigurationIsValid的调用将失败,因为属性I - L将不会映射到SourceParentDestination的映射的目标类型。

You could, of course, write a call to .Ignore for each one, but that would kind of defeat the purpose of getting rid of the nested mapping calls. 当然,你可以为.Ignore编写一个调用,但是这会.Ignore嵌套映射调用的目的。

Your other option would be to leverage this awesome answer to ignore unmapped properties on each of the mappings. 您的另一个选择是利用这个很棒的答案来忽略每个映射上的未映射属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM