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

时间:2020-04-23 09:01:24

标签: c# automapper

有一个question,它描述了我想非常精确地获取的内容,但是他们使用的是内联映射。

源/目的地类型

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

是否有适当的方法可以这样设置配置?


更新

是否可以通过填充SrcInner将Dest映射到SrcOuter?

2 个答案:

答案 0 :(得分:4)

文档介绍了如何使用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();

答案 1 :(得分:1)

我认为您需要查看以下内容:https://docs.automapper.org/en/stable/Projection.html

然后您需要

 .ForMember(dest => dest.A, opt => opt.MapFrom(src => src.C.A))