如何在不使用内联映射或多个 .ForMember 的情况下在 automapper 中映射嵌套对象?

Kai*_*ite 4 c# automapper

有一个问题,它非常精确地描述了我想要得到的内容,但他们使用的是内联映射。

源/目标类型

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;}
}
Run Code Online (Sandbox Code Playgroud)

映射配置

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);
}
Run Code Online (Sandbox Code Playgroud)

预期行为

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有一种正确的方法来设置配置,所以这样的映射会起作用?


更新

有没有办法通过填充 SrcInner 将 Dest 映射到 SrcOuter?

Jon*_*øgh 5

该文档描述了如何使用此处实现IncludeMembers 这一点

在您的情况下,配置将是:

cfg.CreateMap<SrcOuter, Dest>().IncludeMembers(s => s.C);
cfg.CreateMap<SrcInner, Dest>(MemberList.None);
Run Code Online (Sandbox Code Playgroud)

如果您希望它以两种方式工作,最惯用的方法是使用嵌套的源对象名称作为目标成员的前缀,以便展平和非展平自动工作。

例如,如果您有以下对象:

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; }
}
Run Code Online (Sandbox Code Playgroud)

除了以下配置外,您不需要更多配置:

cfg.CreateMap<SrcOuter, Dest>().ReverseMap();
Run Code Online (Sandbox Code Playgroud)