C#-AutoMapper覆盖递归类型

我有一个Dto,看起来像这样:

class TypeDto
{    
    int Id {get; set;}
    string Name {get; set;}
    string DisplayName {get; set;}
    IEnumerable<TypeDto> Children {get; set;}
}

现在,我需要从两个不同的来源映射到它.这是因为其中一个包含Name,另一个包含DisplayName.所以类型:

class Type1
{
    int Id {get; set;}
    string Name {get; set;}
    IEnumerable<Type1> Children {get; set;}
}

class Type2
{
    int Id {get; set;}
    string DisplayName {get; set;}
    IEnumerable<Type2> Nested {get; set;}
}

注意“儿童/嵌套”枚举中的名称差异.

现在为地图做:

config.CreateMap<Type1, TypeDto>();

config.CreateMap<Type2, TypeDto>()
    .ForMember(dest => dest.Children, opts => opts.MapFrom(src => src.Nested));

var dto = _mapper.Map<TypeDto>(type1Instance);

_mapper.Map(type2Instance, dto);

第一个映射按预期工作,递归映射子代,填充Id和Name字段,并在所有地方使DisplayName等于null.但是,第二个映射正确地为根对象填充了DisplayName,但是在其子对象中,它使Name字段无效.因此,例如:

var type1Instance = new Type1 
{ 
    Id = 1, 
    Name = "root", 
    Children = new[] { new Type1 
        {
            Id = 2,
            Name = "child"
        }}
};

var type2Instance = new Type2 
{ 
    Id = 1, 
    DisplayName = "Root", 
    Children = new[] { new Type2
        {
            Id = 2,
            DisplayName = "Child"
        }}
};

映射以下实例后,结果将其字段设置为:

Id = 1,
Name = "root",
DisplayName = "Root",
Children = { TypeDto { Id = 2, Name = null, DisplayName = "Child", Children = null } }

所以孩子的名字无效了,那不是我想要的.显然,我希望它是“孩子”.我应该如何配置映射器以获得所需的行为?

我无法更改Type1或Type2类,它们来自外部API.

AutoMapper的版本是6.2.1,.NET Framework 4.5.1.

解决方法:

摘自Lucian Bargaoanu的评论.

AutoMapper.Collection包解决了我的问题.所需要做的只是将此语句添加到配置中:

config.AddCollectionMappers();

然后在两张地图上定义EqualityComparison:

config.CreateMap<Type1, TypeDto>()
    .EqualityComparison((src, dest) => src.Id == dest.Id);

config.CreateMap<Type2, TypeDto>()
    .EqualityComparison((src, dest) => src.Id == dest.Id)
    .ForMember(dest => dest.Children, opts => opts.MapFrom(src => src.Nested));

之后,集合将正确更新.引用来自here的文档,第二个映射即

_mapper.Map(type2Instance, dto);

现在将在具有匹配ID的任何集合成员上递归映射,添加到集合并映射type2Instance.Nested中dto.Children集合中未出现的所有项目,并删除dto.Children包含但type2Instance.Nested没有的任何项目.

上一篇:C#-Automapper项目从子级访问父级


下一篇:c#-将具有相同名称的字段映射到自动映射器中的不同文件