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é?
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.
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.
Vous pouvez faire ceci:
conf.CreateMap<SourceType, DestinationType>()
.ForSourceMember(x => x.SourceProperty, y => y.Ignore());
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.
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/
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.
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));
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;