Automapper - 如何将源子对象映射到目标对象?

7

我是一个有用的助手,可以为您进行翻译。

我正在尝试从源对象的子对象映射到目标对象(作为父对象)。

源模型:

public class SourceBaseResponse<T> where T : new()
{
    public string Type { get; set; }

    public string Id { get; set; }

    public T Attributes { get; set; }
}

我的例子中,我使用T来表示SourceAssignment类型。

 public class SourceAssignment
{
    public string Id { get; set; }

    public string Email { get; set; }

    public string EmployeeId { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateTimeOffset CreatedAt { get; set; }

}

目标对象

public class DestinationAssignment
{
    public string Id { get; set; }

    public string Email { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

我希望能够直接将源模型映射到目标模型。因此,我尝试使用:
CreateMap<SourceAssignment, DestinationAssignment>();
CreateMap<SourceBaseResponse<SourceAssignment>, DestinationAssignment>()
            .ForMember(dest => dest, opt => opt.MapFrom(src => AutoMapperConfig.Mapper.Map<DestinationAssignment>(src.Attributes)));

这不起作用,因为在上面的代码行中我遇到了运行时错误:“仅支持类型顶级个人成员的自定义成员配置。”

因此,根据这个线程的建议,我尝试了以下方法:

CreateMap<SourceBaseResponse<SourceAssignment>, DestinationAssignment>()
            .AfterMap((src, dst) => Mapper.Map(src.Attributes, dst));

现在,我遇到了一个错误,应该在映射时发生,提示“未初始化Mapper。使用适当的配置调用Initialize。如果您正在通过容器或其他方式使用映射器实例,请确保没有任何对静态Mapper.Map方法的调用,并且如果您正在使用ProjectTo或UseAsDataSource扩展方法,请确保传递适当的IConfigurationProvider实例。”
我能够为每个属性使用ForMember,并将其从src.Attributes映射到dest(例如:src.Attribute.Id到dest.Id)。这有效,但我真的不想这样做,因为我的源是涉及嵌套子项的复杂类(因为这是Web API响应,我无法控制此类)。因此,在这里进行了大量的自定义映射。
CreateMap<SourceAssignment, DestinationAssignment>();

有关如何继续的任何建议。


AfterMap表达式使用静态的Mapper,因此请确保它已配置(即静态映射器具有SourceAssignment->DestinationAssignment的映射)。也许您当前正在配置一个实例而不是静态映射器? - Georg Patscheider
@GeorgPatscheider 这是一个静态映射器。如果不是从SourceBaseResponse进行映射,我可以使用它来自动映射源到目标。 - Sumesh Kuttan
1个回答

11

为了能够调用Mapper.Map(),需要解析上下文,您可以使用ConstructUsing()来获取解析上下文:

CreateMap<SourceChild, Destination>();
CreateMap<Source, Destination>()
    .ConstructUsing((src, ctx) => ctx.Mapper.Map<Destination>(src.SourceChild));

这个工作很好,除了在测试中。当使用这个创建MapperConfiguration时,config.AssertConfigurationIsValid()仍然失败,声称子对象的属性未映射。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接