c# - unmapped - automapper ignore null
¿Cómo ignorar la propiedad de la propiedad en la asignación de AutoMapper? (2)
Creo que el problema que está experimentando proviene de la suposición equivocada de que los Grupos en PersonDTO.Groups son los mismos que GroupDTO, no puede ser así sin el ciclo de dependencia infinito. El siguiente código debería funcionar para usted:
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()
});
Básicamente, debes enseñarle a AutoMapper que, en el caso de propiedad PersonDTO.Groups, debe asignar los objetos de GroupDTO de forma diferente.
Pero creo que su problema es más un problema arquitectónico que el código uno. Los PersonDTO.Groups no deben ser de tipo GroupDTO; solo te interesan los grupos a los que pertenece un usuario en particular y no a otros miembros de sus grupos. Deberías tener un tipo más simple como:
public class PersonGroupDTO
{
public string Name { get; set; }
}
(el nombre depende de ti, por supuesto) para identificar solo al grupo sin pasar miembros adicionales.
Imagen una Person
y una clase Group
con una relación de muchos a muchos. Una persona tiene una lista de grupos y un grupo tiene una lista de personas.
Cuando mapeo Person
to PersonDTO
tengo una stack overflow exception
porque AutoMapper no puede manejar Person
> Groups
> Members
> Groups
> Members
> ...
Así que aquí está el código de ejemplo:
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; }
}
Cuando uso .ForMember para crear un asignador, el primer mapeador que se ejecuta arroja una null reference exception
.
Aquí está el código para el mapeador:
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();
Entonces, ¿qué estoy perdiendo o haciendo mal? Cuando elimino los métodos .ForMember, la null reference exception
ya no se lanza.
ACTUALIZACIÓN : Realmente quiero enfatizar que el punto principal de mi pregunta es cómo ignorar una propiedad de una propiedad . Este código es solo un ejemplo bastante simple.
ACTUALIZACIÓN 2: Así es como lo arreglé, muchas gracias a 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();
¡Gracias a .PreserveReferences()
las referencias circulares se arreglan!
Esto debería funcionar. Ver https://github.com/AutoMapper/AutoMapper/wiki/5.0-Upgrade-Guide#circular-references . También hay un PR pendiente https://github.com/AutoMapper/AutoMapper/pull/2233 .