忽略一个属性与Automapper的映射

我正在使用Automapper,我有以下场景: 类OrderModel有一个名为“ProductName”的属性,该属性不在数据库中。 当我尝试用

进行映射时
Mapper.CreateMap<OrderModel, Orders>();

它会生成一个异常:

" Project.ViewModels.OrderModel上的以下1个属性没有被映射:

我在AutoMapper的投影Wiki读到了相反的情况(额外的属性在目标上,而不是在源中,这实际上是我的情况)

我如何避免自动程序使这个属性的映射?

312383 次浏览

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

它在他博客上的一条评论中。

UPDATE(from 杰米的 comment 1月4日19日11:11:)

Ignore已经在ForSourceMember中替换为DoNotValidate: https://github.com/AutoMapper/AutoMapper/blob/master/docs/8.0-Upgrade-Guide.md < / p >

现在(AutoMapper 2.0)有一个IgnoreMap属性,我将使用它而不是流畅的语法,这是一个有点沉重的恕我直言。

你可以这样做:

conf.CreateMap<SourceType, DestinationType>()
.ForSourceMember(x => x.SourceProperty, y => y.Ignore());

或者,在最新版本的Automapper中,您只需告诉Automapper不验证该字段

conf.CreateMap<SourceType, DestinationType>()
.ForSourceMember(x => x.SourceProperty, y => y.DoNotValidate());

对于任何试图自动执行此操作的人来说,您可以使用扩展方法忽略目标类型上不存在的属性:

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

使用方法如下:

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

感谢Can Gencer的建议:)

< p >来源: http://cangencer.wordpress.com/2011/06/08/auto-ignore-non-existing-properties-with-automapper/ < / p >

我可能是一个完美主义者;我真的不喜欢ForMember(..., x => x.Ignore())语法。这是件小事,但对我很重要。我写了这个扩展方法,使它更好一点:

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

它可以这样使用:

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

你也可以重写它来使用params,但我不喜欢一个有大量lambda的方法。

当将视图模型映射回域模型时,只需验证源成员列表而不是目标成员列表就可以清晰得多

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

现在我的映射验证不会失败,每次向域类添加属性时都需要另一个Ignore()

大家好,请使用这个,它工作得很好…对于自动映射器使用多个.ForMember在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;

可以使用IgnoreAttribute属性需要被忽略

也可以忽略像这样的全局属性:

  1. 在映射器配置中使用AddGlobalIgnore(string propertyNameStartingWith)方法忽略名称以指定字符串开头的属性。
  2. 使用ShouldMapProperty提供一个谓词,并有条件地选择要映射的属性。ShouldMapFieldShouldMapMethod属性也是可用的。

用法:

public class MappingProfile : Profile
{
public MappingProfile()
{
// other configs...


AddGlobalIgnore("foo")); // this will ignore properties with name starting with "foo"
ShouldMapProperty = p => p.Name != "bar"; // this will ignore properties with name "bar"
}
}

或者:

var config = new MapperConfiguration(cfg => {
// other configs...
cfg.AddGlobalIgnore("foo"); // way 1
cfg.ShouldMapProperty = p => p.Name != "bar"; // way 2
});