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

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

Person映射到PersonDTO我有一个stack overflow exception因为AutoMapper无法处理Person > Groups > Members > Groups > Members > …

所以这是示例代码:

 public class Person { public string Name { get; set; } public List Groups { get; set; } } public class Group { public string Name { get; set; } public List Members { get; set; } } public class PersonDTO { public string Name { get; set; } public List Groups { get; set; } } public class GroupDTO { public string Name { get; set; } public List Members { get; set; } } 

当我在创建映射器时使用.ForMember时,第一个被执行的映射器会抛出一个null reference exception

这是映射器的代码:

 CreateMap() .ForMember(x => x.Groups.Select(y => y.Members), opt => opt.Ignore()) .ReverseMap(); CreateMap() .ForMember(x => x.Members.Select(y => y.Groups), opt => opt.Ignore()) .ReverseMap(); 

那么我错过了什么或做错了什么? 当我删除.ForMember方法时,不再抛出null reference exception

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

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

 CreateMap() .ForMember(x => x.Groups.Select(y => y.Members), opt => opt.Ignore()) .PreserveReferences() // This is the solution! .ReverseMap(); CreateMap() .ForMember(x => x.Members.Select(y => y.Groups), opt => opt.Ignore()) .PreserveReferences() // This is the solution! .ReverseMap(); 

感谢.PreserveReferences()循环引用得到修复!

这应该工作。 请参阅https://github.com/AutoMapper/AutoMapper/wiki/5.0-Upgrade-Guide#circular-references 。 还有一个PR待定https://github.com/AutoMapper/AutoMapper/pull/2233 。

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

 CreateMap() .ForMember(x => x.Groups, opt => opt.Ignore()) .ReverseMap() .AfterMap((src, dest) => { dest.Groups = src.Groups.Select(g => new GroupDTO { Name = g.Name }).ToList() }); CreateMap() .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; } } 

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