web-dev-qa-db-fra.com

Comment ignorer tous les membres de destination, à l'exception de ceux qui sont mappés?

Y a-t-il un moyen de faire cela? Nous avons un SummaryDto qui mappe à partir de trois types différents, et lorsque nous créons une carte pour chaque type, les accessoires qui ne sont pas mappés génèrent une erreur. Le résumé dto contient environ 35 attributs. Utiliser l'option Ignore () sur chacun d'eux est tout simplement trop compliqué. Y a-t-il une ignorance globale? Quelque chose comme

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

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, appeler ForAllMembers(o => o.Ignore()) sans cette méthode d'extension ne fonctionnerait pas. Nous voulons conserver l'expression de mappage disponible pour activer les mappages suivants:

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

J'ai également eu du mal avec celui-ci pendant un bon moment, ou du moins un problème similaire à celui-ci. J'avais une classe avec beaucoup de propriétés (environ 30) et je voulais seulement en cartographier environ 4. Il semble fou d'ajouter 26 instructions ignorer (surtout quand cela signifie que les futurs changements de classe signifieront devoir les mettre à jour!)

J'ai finalement trouvé 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));

Vous seriez pardonné de penser que vous pourriez simplement faire cela (mais pas parce qu'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 prend pas en charge le style de chaînage fluide (au moins dans la version actuelle 2.0).

La bonne nouvelle est que la version sans chaînage fonctionne effectivement. La seule mise en garde est bien sûr que vous devez indiquer explicitement à AutoMapper quels membres mapper. Je n'ai pas encore trouvé de moyen simple de procéder dans les deux sens afin que vous puissiez toujours utiliser les mappages implicites et ignorer ceux qui sont brisés.

30
Nicholas Green

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

5
Edward Brey

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 souhaitez avoir dans votre objet, les autres seront ignorées.

1
Vladimir Dorokhov

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;
}

Usage:

L'appel à IgnoreAllMembers doit être avant l'appel à ForMember.

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