65 votes

Comment ignorer tous les membres de la destination, sauf ceux qui sont mappés ?

Y a-t-il un moyen de le faire ? Nous avons un SummaryDto qui mappe à partir de trois types différents, et lorsque nous créons une carte pour chaque type, les props qui ne sont pas mappés jettent une erreur. Il y a environ 35 attributs sur le SummaryDto. Utiliser l'option Ignore() pour chacun d'entre eux est tout simplement trop compliqué. Existe-t-il une option Ignore globale ? Quelque chose comme

CreateMap<Source,Target>()
   .IgnoreAllUnmapped();

117voto

CodeMonkeyKing Points 1882

Cela fonctionne pour moi :

public static class MappingExpressionExtensions
{
    public static IMappingExpression<TSource, TDest> IgnoreAllUnmapped<TSource, TDest>(this IMappingExpression<TSource, TDest> expression)
    {
        expression.ForAllMembers(opt => opt.Ignore());
        return expression;
    }
}

Parce que ForAllMembers renvoie à void en appelant ForAllMembers(o => o.Ignore()) sans cette méthode d'extension ne fonctionnerait pas. Nous voulons garder l'expression de mappage disponible pour permettre les mappages ultérieurs :

CreateMap<Source, Destination>()
            .IgnoreAllUnmapped()
            .ForMember(d => d.Text, o => o.MapFrom(s => s.Name))
            .ForMember(d => d.Value, o => o.MapFrom(s => s.Id));

30voto

Nicholas Green Points 187

J'ai lutté avec celui-ci pendant un certain temps aussi, ou du moins un problème similaire à celui-ci. J'avais une classe avec beaucoup de propriétés (environ 30) et je ne voulais cartographier que 4 d'entre elles. Il semble fou d'ajouter 26 déclarations d'ignorance (surtout quand cela signifie que les futures modifications de la classe impliqueront de les mettre à jour !)

J'ai finalement découvert que je pouvais dire à AutoMapper de tout ignorer, puis d'ajouter explicitement ceux que je voulais.

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

On pourrait vous pardonner de penser que vous pouvez simplement faire cela (mais ne le faites pas car il ne compilera pas) :

// This won't compile
CreateMap<Source,Target>()
   .ForAllMembers(opt => opt.Ignore())
   .ForMember(dest => dest.P1, opt => opt.MapFrom( src => src.P1));

La raison pour laquelle cela ne fonctionne pas est que la méthode ForAllMembers() ne supporte pas le style fluide de chaînage (du moins dans la version actuelle 2.0).

La bonne nouvelle est que la version sans chaînage fonctionne effectivement. Le seul problème, bien sûr, est que vous devez indiquer explicitement à AutoMapper les membres à mettre en correspondance. Je n'ai pas encore trouvé de moyen facile de faire les deux, de façon à pouvoir utiliser les mappings implicites et ignorer ceux qui sont cassés.

5voto

Edward Brey Points 8771

Pour éviter d'avoir à spécifier explicitement les propriétés mappées, vous pouvez utiliser la commande IgnoreAllNonExisting . Il ignore toutes les propriétés de destination qui n'ont pas de propriétés source mappées.

1voto

Vladimir Dorokhov Points 2581

Essayez d'utiliser .ConvertUsing() dans votre cas, par exemple

CreateMap<Source,Target>()
 .ConvertUsing(converter=> new Target(){
P1 = converter.P1,
....
});

Ainsi, vous pouvez décrire toutes les propriétés que vous voulez avoir dans votre objet, les autres seront ignorées.

1voto

Casey Points 161

Méthode d'extension qui permet une syntaxe fluide pour la méthode ForAllMembers :

public static IMappingExpression<TSource, TDestination> IgnoreAllMembers<TSource, TDestination>(
    this IMappingExpression<TSource, TDestination> expression
    )
{
    expression.ForAllMembers(opt => opt.Ignore());
    return expression;
}

Utilisation :

L'appel à IgnoreAllMembers doit précéder l'appel à ForMember.

        CreateMap<LocationRevision, Dto.LocationAddressMap>()
            .IgnoreAllMembers()
            .ForMember(m => m.LocationId, opt => opt.MapFrom(src => src.Id))
            ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X