c# - visa - ¿Cómo ignorar a todos los miembros de destino, excepto los que están mapeados?
visado schengen (5)
Esta pregunta ya tiene una respuesta aquí:
- AutoMapper: "Ignorar el resto"? 16 respuestas
¿Hay alguna forma de hacer esto? Tenemos un resumen de esos mapas de tres tipos diferentes, y cuando creamos un mapa para cada tipo, los accesorios que no están mapeados arrojan un error. Hay aproximadamente 35 atributos en el resumen dto. Usar la opción Ignorar () en cada uno es demasiado problema. ¿Hay una ignorancia global? Algo como
CreateMap<Source,Target>()
.IgnoreAllUnmapped();
Esto es trabajo para mí:
public static class MappingExpressionExtensions
{
public static IMappingExpression<TSource, TDest> IgnoreAllUnmapped<TSource, TDest>(this IMappingExpression<TSource, TDest> expression)
{
expression.ForAllMembers(opt => opt.Ignore());
return expression;
}
}
Como ForAllMembers
devuelve void
, llamar a ForAllMembers(o => o.Ignore())
sin este método de extensión no funcionaría. Queremos mantener la expresión de mapeo disponible para habilitar las siguientes asignaciones:
CreateMap<Source, Destination>()
.IgnoreAllUnmapped()
.ForMember(d => d.Text, o => o.MapFrom(s => s.Name))
.ForMember(d => d.Value, o => o.MapFrom(s => s.Id));
Intenta usar .ConvertUsing()
en tu caso, por ej.
CreateMap<Source,Target>()
.ConvertUsing(converter=> new Target(){
P1 = converter.P1,
....
});
Por lo tanto, puede describir todas las propiedades que desea tener en su objeto, otras serán ignoradas.
Luché con este durante bastante tiempo también, o al menos un problema similar a esto. Tenía una clase con muchas propiedades (alrededor de 30) y solo quería hacer un mapa de 4 de ellas. Parece una locura agregar 26 declaraciones de ignorar (¡especialmente cuando significa que los cambios futuros en la clase significarán tener que actualizarlos!)
Finalmente descubrí que podía decirle a AutoMapper que ignorara todo y luego añadiera explícitamente los que yo quería.
// Create a map, store a reference to it in a local variable
var map = CreateMap<Source,Target>();
// Ignore all members
map.ForAllMembers(opt => opt.Ignore());
// Add mapping for P1
map.ForMember(dest => dest.P1, opt => opt.MapFrom( src => src.P1));
// Add other mappings...
map.ForMember(dest => dest.P2, opt => opt.MapFrom( src => src.P2));
map.ForMember(dest => dest.P3, opt => opt.MapFrom( src => src.P3));
map.ForMember(dest => dest.P4, opt => opt.MapFrom( src => src.P4));
Serás perdonado por pensar que podrías hacer esto (pero no porque no compilará):
// This won''t compile
CreateMap<Source,Target>()
.ForAllMembers(opt => opt.Ignore())
.ForMember(dest => dest.P1, opt => opt.MapFrom( src => src.P1));
La razón por la que esto no funciona es que el método ForAllMembers () no admite el estilo fluido de encadenamiento (al menos en la versión actual 2.0).
La buena noticia es que la versión no encadenable sí funciona. La única advertencia es que debe indicar explícitamente a AutoMapper qué miembros deben mapear. Todavía no he encontrado una manera fácil de tener ambas formas, por lo que aún puedes usar las asignaciones implícitas e ignorar las que están rotas.
Método de extensión que permite una sintaxis fluida para el método ForAllMembers:
public static IMappingExpression<TSource, TDestination> IgnoreAllMembers<TSource, TDestination>(
this IMappingExpression<TSource, TDestination> expression
)
{
expression.ForAllMembers(opt => opt.Ignore());
return expression;
}
Uso:
La llamada a IgnoreAllMembers debe ser anterior a la llamada a ForMember.
CreateMap<LocationRevision, Dto.LocationAddressMap>()
.IgnoreAllMembers()
.ForMember(m => m.LocationId, opt => opt.MapFrom(src => src.Id))
;
Para evitar tener que especificar explícitamente las propiedades mapeadas, puede usar IgnoreAllNonExisting . Ignora las propiedades de destino que no tienen propiedades de origen mapeadas.