如何在AutoMapper映射中忽略属性的属性?

时间:2017-07-25 08:39:43

标签: c# entity-framework automapper stack-overflow nullreferenceexception

想象一个具有多对多关系的PersonGroup类。一个人有一个组列表,一个组有一个人员列表。

Person映射到PersonDTO时我有stack overflow exception,因为AutoMapper无法处理Person> Groups> {{1 }}> Members> Groups> ...

以下是示例代码:

Members

当我在创建映射器时使用.ForMember时,第一个被执行的映射器会抛出public class Person { public string Name { get; set; } public List<Group> Groups { get; set; } } public class Group { public string Name { get; set; } public List<Person> Members { get; set; } } public class PersonDTO { public string Name { get; set; } public List<GroupDTO> Groups { get; set; } } public class GroupDTO { public string Name { get; set; } public List<PersonDTO> Members { get; set; } }

这是映射器的代码:

null reference exception

那么我错过了什么或做错了什么?当我删除.ForMember方法时,CreateMap<Person, PersonDTO>() .ForMember(x => x.Groups.Select(y => y.Members), opt => opt.Ignore()) .ReverseMap(); CreateMap<Group, GroupDTO>() .ForMember(x => x.Members.Select(y => y.Groups), opt => opt.Ignore()) .ReverseMap(); 不再被抛出。

更新:我真的想强调我的问题的要点如何忽略属性的属性。这段代码只是一个相当简单的例子。

更新2:这是我修复它的方式,非常感谢Lucian-Bargaoanu

null reference exception

感谢CreateMap<Person, PersonDTO>() .ForMember(x => x.Groups.Select(y => y.Members), opt => opt.Ignore()) .PreserveReferences() // This is the solution! .ReverseMap(); CreateMap<Group, GroupDTO>() .ForMember(x => x.Members.Select(y => y.Groups), opt => opt.Ignore()) .PreserveReferences() // This is the solution! .ReverseMap(); 循环引用得到修复!

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

我认为您遇到的问题来自错误的假设,即PersonDTO.Groups中的Groups与GroupDTO相同 - 没有无限依赖循环就不能这样。以下代码适合您:

CreateMap<Person, PersonDTO>()
    .ForMember(x => x.Groups, opt => opt.Ignore())
    .ReverseMap()
    .AfterMap((src, dest) => 
    {
        dest.Groups = src.Groups.Select(g => new GroupDTO { Name = g.Name }).ToList()
    });

CreateMap<Group, GroupDTO>()
    .ForMember(x => x.Members, opt => opt.Ignore())
    .ReverseMap()
    .AfterMap((src, dest) => 
    {
        dest.Members = src.Members.Select(p => new PersonDTO { Name = p.Name }).ToList()
    });

你基本上需要教AutoMapper,在PersonDTO.Groups属性的情况下,它应该以不同的方式映射GroupDTO对象。

但我认为你的问题更像是建筑问题,而不是代码问题。 PersonDTO.Groups不应该是GroupDTO类型 - 您只对特定用户所属的组感兴趣,而不是对其组的其他成员感兴趣。你应该有一些更简单的类型:

public class PersonGroupDTO
{
    public string Name { get; set; }
}

(当然,这个名称取决于您)只能在不通过其他成员的情况下识别该组。