2017-09-15 1 views
5

Contexte:AutoMapper: Ignorer élément de dictionnaire spécifique (s) au cours de la cartographie

Il 2 classes principales qui ont l'air quelque chose comme ceci:

public class Source 
{ 
    public Dictionary<AttributeType, object> Attributes { get; set; } 
} 

public class Target 
{ 
    public string Title { get; set; } 
    public string Description { get; set; } 
    public List<Attribute> Attributes { get; set; } 
} 

Et sous/collection/types Enum:

public class Attribute 
{ 
    public string Name { get; set; } 
    public string Value { get; set; } 
} 

public enum AttributeType 
{ 
    Title, 
    Description, 
    SomethingElse, 
    Foobar 
} 

Actuellement ma carte ressemble à ceci:

CreateMap<Source, Target>() 
    .ForMember(dest => dest.Description, opt => opt.MapAttribute(AttributeType.Description)) 
    .ForMember(dest => dest.Title, opt => opt.MapAttribute(AttributeType.Title)); 

MapAttribute obtient l'élément de la Dictionary et en utilisant le AttributeType j'ai fourni, ajoute à la collection cible comme un objet (en utilisant un essai obtenir et retourner un vide si la clé (nom valeur &) n'existe pas) ...

Après tout cela ma fin objectif fixé par ressembler à ceci:

{ 
    title: "Foo", 
    attributes: [ 
    { name: "SomethingElse", value: "Bar" }, 
    { name: "Title", value: "Foo"} 
    ] 
} 


question:

Comment faire pour mapper le reste des éléments à la classe cible, mais je dois pouvoir exclure des clés spécifiques (comme, titre ou description). PAR EXEMPLE. Les éléments Source.Attribute qui ont un emplacement défini dans la cible sont exclus de la collection Target.Attributes et les propriétés "left-over" continuent d'être affectées à Target.Attributes.

Pour encore plus de clarté (si ma source ressemble à ceci):

{ attributes: { title: "Foo", somethingelse: "Bar" } } 

il la carte à une cible comme ceci:

{ title: "Foo", attributes: [{ name: "SomethingElse", value: "Bar" }] } 

J'ai essayé, mais il ne compile pas, en indiquant ce qui suit:

Configuration personnalisée pour les membres est pris en charge uniquement pour les membres individuels de niveau supérieur sur un type.

CreateMap<KeyValuePair<AttributeType, object>, Attribute>() 
    .ForSourceMember(x => x.Key == AttributeType.CompanyName, y => y.Ignore()) 

Répondre

3

Il est possible de valeurs prefilter sur la configuration de la cartographie, que certaines valeurs ne même pas aller à la cible J'utilise automapper v6.1.1, il y a une certaine différence, mais l'idée devrait être le même)

Pour rendre les choses fonctionne, je dois ajouter KeyValuePair<AttributeType, object>-Attribute mappage premier (MapAttribute retourne juste valeur dictionnaire)

CreateMap<KeyValuePair<AttributeType, object>, Attribute>() 
    .ForMember(dest => dest.Name, opt => opt.MapFrom(s => s.Key)) 
    .ForMember(dest => dest.Value, opt => opt.MapFrom(s => s.Value)); 

Comme il est défini quels attributs doivent être ignorés, ils vont va ignorer la liste, sur la base duquel la cartographie filtrera l'excès d'attributs

var ignoreAttributes = new[] {AttributeType.Description, AttributeType.Title}; 
CreateMap<Source, Target>() 
    .ForMember(dest => dest.Description, opt => opt.MapFrom(s => s.MapAttribute(AttributeType.Description))) 
    .ForMember(dest => dest.Title, opt => opt.MapFrom(s => s.MapAttribute(AttributeType.Title))) 
    .ForMember(dest=>dest.Attributes, opt=> opt.MapFrom(s=>s.Attributes 
     .Where(x=> !ignoreAttributes.Contains(x.Key)))); 

basé sur l'exemple de la cartographie finale

var result = Mapper.Map<Target>(new Source 
{ 
    Attributes = new Dictionary<AttributeType, object> 
    { 
     {AttributeType.Description, "Description"}, 
     {AttributeType.Title, "Title"}, 
     {AttributeType.SomethingElse, "Other"}, 
    } 
}); 
résultat

aura rempli Titel, la description et juste un attribut SomethingElse

enter image description here enter image description here