使用AutoMapper,如何在不使用AfterMap的情况下从映射的父集合成员获取值

本文关键字:映射 情况下 集合 获取 成员 AfterMap AutoMapper 使用 | 更新日期: 2023-09-27 18:21:02

假设如下:

public class ParentSource
{
    public Guid parentId { get; set; }
    public ICollection<ChildSource> children { get; set; }
}
public class ChildSource
{
    public Guid childId { get; set; }
}
public class ParentDestination
{
    public Guid parentId { get; set; }
    public ICollection<ChildDestination> children { get; set; }
}
public class ChildDestination
{
    public Guid childId { get; set; }
    public Guid parentId { get; set; }
    public ParentDestination parent;
}

在不使用.AfterMap的情况下,如何使用AutoMapper用父对象的信息填充ChildDestination对象?

使用AutoMapper,如何在不使用AfterMap的情况下从映射的父集合成员获取值

我认为,在不使用.AfterMap()的情况下,通过引用成员集合的父实例来填充集合中的子对象的唯一方法是使用自定义TypeConverter<TSource, TDestination>

class Program
{
    static void Main(string[] args)
    {
        AutoMapper.Mapper.CreateMap<ParentSource, ParentDestination>().ConvertUsing<CustomTypeConverter>();
        ParentSource ps = new ParentSource() { parentId = Guid.NewGuid() };
        for (int i = 0; i < 3; i++)
        {
            ps.children.Add(new ChildSource() { childId = Guid.NewGuid() });
        }
        var mappedObject = AutoMapper.Mapper.Map<ParentDestination>(ps);
    }
}
public class ParentSource
{
    public ParentSource()
    {
        children = new HashSet<ChildSource>();
    }
    public Guid parentId { get; set; }
    public ICollection<ChildSource> children { get; set; }
}
public class ChildSource
{
    public Guid childId { get; set; }
}
public class ParentDestination
{
    public ParentDestination()
    {
        children = new HashSet<ChildDestination>();
    }
    public Guid parentId { get; set; }
    public ICollection<ChildDestination> children { get; set; }
}
public class ChildDestination
{
    public Guid childId { get; set; }
    public Guid parentId { get; set; }
    public ParentDestination parent { get; set; }
}
public class CustomTypeConverter : AutoMapper.TypeConverter<ParentSource, ParentDestination>
{
    protected override ParentDestination ConvertCore(ParentSource source)
    {
        var result = new ParentDestination() { parentId = source.parentId };
        result.children = source.children.Select(c => new ChildDestination() { childId = c.childId, parentId = source.parentId, parent = result }).ToList();
        return result;
    }
}

或者您可以使用.AfterMap().:)

正如您在评论中所说,如果您不想使用AfterMap,ForMember将是另一个选项。您可以创建一个ForMember转换器,使用linq可以非常快速地循环通过源子级,将它们转换为目标子级,然后设置Parent属性。

或者您可以使用AfterMap。:)

更新:

也许是这样的(未经测试):

.ForMember(d => d.children, 
    o => o.MapFrom(s => 
        from child in s.children
        select new ChildDestination {
            childId = child.childId,
            parentId = s.parentId,
            parent = s
        }));