如何在不使用内联映射或多个 .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))