Ignorer le mappage d'une propriété avec Automapper

J'utilise Automapper et j'ai le scénario suivant: Class OrderModel a une propriété appelée 'ProductName' qui n'est pas dans la base de données. Donc, quand j'essaie de faire le mappage avec:

Mapper.CreateMap<OrderModel, Orders>(); 

, Il génère une exception :

" les 1 propriétés suivantes sur le projet.Viewmodel.OrderModel ne sont pas mappés: 'ProductName'

J'ai lu sur le Wiki D'AutoMapper pour les Projections le cas inverse (l'attribut supplémentaire est sur la destination, pas dans la source qui est réellement mon cas )

Comment puis-je éviter automapper pour faire le mappage de cette propriété?

210
demandé sur Andries Koorzen 2011-02-14 03:22:53

8 réponses

De Jimmy Bogard: CreateMap<Foo, Bar>().ForMember(x => x.Blarg, opt => opt.Ignore());

C'est dans l'un des commentaires sur son blog.

340
répondu smartcaveman 2011-11-27 12:28:53

Je suis peut-être un peu perfectionniste; je n'aime pas vraiment le ForMember (..., X = > X. Ignore()) syntaxe. C'est une petite chose, mais c'est important pour moi. J'ai écrit cette méthode d'extension pour la rendre un peu plus agréable:

public static IMappingExpression<TSource, TDestination> Ignore<TSource, TDestination>(
    this IMappingExpression<TSource, TDestination> map,
    Expression<Func<TDestination, object>> selector)
{
    map.ForMember(selector, config => config.Ignore());
    return map;
}

Il peut être utilisé comme ceci:

Mapper.CreateMap<JsonRecord, DatabaseRecord>()
        .Ignore(record => record.Field)
        .Ignore(record => record.AnotherField)
        .Ignore(record => record.Etc);

Vous pouvez également réécrire à travailler avec params, mais je n'aime pas le look d'une méthode avec des charges de lambdas.

207
répondu Steve Rukuts 2013-05-29 08:23:56

Vous pouvez faire ceci:

conf.CreateMap<SourceType, DestinationType>()
   .ForSourceMember(x => x.SourceProperty, y => y.Ignore());
69
répondu Richard 2012-04-16 19:12:42

Il y a maintenant (AutoMapper 2.0) un attribut IgnoreMap, que je vais utiliser plutôt que la syntaxe fluide qui est un peu lourde à mon humble avis.

25
répondu Guillaume 2011-09-23 08:45:51

Juste pour quiconque essaie de le faire automatiquement, vous pouvez utiliser cette méthode d'extension pour ignorer les propriétés non existantes sur le type de destination:

public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
    var sourceType = typeof(TSource);
    var destinationType = typeof(TDestination);
    var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType)
        && x.DestinationType.Equals(destinationType));
    foreach (var property in existingMaps.GetUnmappedPropertyNames())
    {
        expression.ForMember(property, opt => opt.Ignore());
    }
    return expression;
}

À utiliser comme suit:

Mapper.CreateMap<SourceType, DestinationType>().IgnoreAllNonExisting();

Merci à Can Gencer pour l'astuce:)

Source : http://cangencer.wordpress.com/2011/06/08/auto-ignore-non-existing-properties-with-automapper/

24
répondu Stéphane 2013-02-13 15:30:19

Lors du mappage d'un modèle de vue vers un modèle de domaine, il peut être beaucoup plus simple de valider simplement la liste des membres source plutôt que la liste des membres de destination

Mapper.CreateMap<OrderModel, Orders>(MemberList.Source); 

Maintenant, ma validation de mappage n'échoue pas, nécessitant un autre Ignore(), chaque fois que j'ajoute une propriété à ma classe de domaine.

10
répondu Loren Paulsen 2015-06-15 03:49:07

J'ai apprécié une extension ajoutée par Steve Rukuts, alors j'ai décidé d'ajouter une autre méthode d'extension basée sur son exemple. J'espère que cela aidera quelqu'un:

    public static IMappingExpression<TSource, TDestination> Map<TSource, TDestination>(
        this IMappingExpression<TSource, TDestination> map,
        Expression<Func<TSource, object>> src,
        Expression<Func<TDestination, object>> dst)
    {
        map.ForMember(dst, opt => opt.MapFrom(src));
        return map;
    }

Utilisation:

    Mapper.Initialize(cfg => cfg.CreateMap<UserModel, UserDto>()
        .Map(src => src.FirstName + " " + src.LastName, dst => dst.UserName));
-2
répondu Alex Valchuk 2016-12-08 09:12:51

Bonjour à tous, utilisez ceci, cela fonctionne bien... pour le mappeur automatique, Utilisez plusieurs .ForMember en C #

        if (promotionCode.Any())
        {
            Mapper.Reset();
            Mapper.CreateMap<PromotionCode, PromotionCodeEntity>().ForMember(d => d.serverTime, o => o.MapFrom(s => s.promotionCodeId == null ? "date" : String.Format("{0:dd/MM/yyyy h:mm:ss tt}", DateTime.UtcNow.AddHours(7.0))))
                .ForMember(d => d.day, p => p.MapFrom(s => s.code != "" ? LeftTime(Convert.ToInt32(s.quantity), Convert.ToString(s.expiryDate), Convert.ToString(DateTime.UtcNow.AddHours(7.0))) : "Day"))
                .ForMember(d => d.subCategoryname, o => o.MapFrom(s => s.subCategoryId == 0 ? "" : Convert.ToString(subCategory.Where(z => z.subCategoryId.Equals(s.subCategoryId)).FirstOrDefault().subCategoryName)))
                .ForMember(d => d.optionalCategoryName, o => o.MapFrom(s => s.optCategoryId == 0 ? "" : Convert.ToString(optionalCategory.Where(z => z.optCategoryId.Equals(s.optCategoryId)).FirstOrDefault().optCategoryName)))
                .ForMember(d => d.logoImg, o => o.MapFrom(s => s.vendorId == 0 ? "" : Convert.ToString(vendorImg.Where(z => z.vendorId.Equals(s.vendorId)).FirstOrDefault().logoImg)))
                .ForMember(d => d.expiryDate, o => o.MapFrom(s => s.expiryDate == null ? "" : String.Format("{0:dd/MM/yyyy h:mm:ss tt}", s.expiryDate))); 
            var userPromotionModel = Mapper.Map<List<PromotionCode>, List<PromotionCodeEntity>>(promotionCode);
            return userPromotionModel;
        }
        return null;
-3
répondu ravikant sonare 2015-12-22 14:04:38