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

How to ignore property of property in AutoMapper mapping?

图像PersonGroupclass具有多对多关系。一个人有一个组列表,一个组有一个人列表。

当映射 PersonPersonDTO 我有一个 stack overflow exception 因为 AutoMapper 不能处理 Person>Groups>Members >Groups>Members>...

下面是示例代码:

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; }
}

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

这是映射器的代码:

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();

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

更新:我真的想强调我的问题的要点如何忽略[= 属性 的 56=]。此代码只是一个相当简单的示例。

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

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();

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

我认为您遇到的问题来自错误的假设,即 PersonDTO.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; }
}

(名字当然由你决定)只识别组而不传递额外的成员。

这应该行得通。参见 https://github.com/AutoMapper/AutoMapper/wiki/5.0-Upgrade-Guide#circular-references. There is also a PR pending https://github.com/AutoMapper/AutoMapper/pull/2233