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