2

图片a PersonGroup类与多对多的关系。一个人有一个组的列表,一个组有一个人的列表。如何在AutoMapper映射中忽略属性的属性?

当映射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不再被抛出。

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

更新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()循环引用拿不动!

+0

谢谢@Esperadoce,但我的代码比示例稍微简单一些。我真的想在AutoMapper中忽略属性**的**属性。 – Mason

+1

是的,你是对的,我删除我的国旗! – Esperadoce

+0

是@KirillShlenskiy,他们确实是领域,我只是想保持它非常简单。我会更新我的问题。 – Mason

回答

2
+0

是的!哦,我的魔杖修复了它!非常感谢!我希望我不会使用很多丑陋的代码,但是只是添加'.PreserveReferences()'来修复它!再次感谢你。 – Mason

+1

一个潜在解决方案的链接总是受欢迎的,但请[在链接周围添加上下文](// meta.stackoverflow.com/a/8259),以便您的同行用户可以了解它是什么以及它为什么在那里。 **如果目标网站无法访问或永久离线,请务必引用重要链接中最相关的部分**考虑到_仅仅是链接到外部网站_是可能的原因,因为[Why and如何删除一些答案?](// stackoverflow.com/help/deleted-answers)。 – kayess

2

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

(名字由你当然)。

+0

谢谢您的回答。那是我尝试过的方式,但它看起来并不那么干净,不得不为了解决这个问题而制作单独的DTO。我用一个非常简单的解决方案更新了我的问题,以使用automapper修复循环引用。 – Mason

+1

只考虑到使用PreserveReferences在一定程度上减慢了automapper :)除了你没事。 – mr100