Automapper:根据条件忽略映射

40

根据源属性的值是否需要忽略映射成员,这种情况是否可能?

例如,如果我们有:

public class Car
{
    public int Id { get; set; }
    public string Code { get; set; }
}

public class CarViewModel
{
    public int Id { get; set; }
    public string Code { get; set; }
}
我正在寻找类似于什么样的东西。
Mapper.CreateMap<CarViewModel, Car>()
      .ForMember(dest => dest.Code, 
      opt => opt.Ignore().If(source => source.Id == 0))

到目前为止,我唯一的解决方案是使用两个不同的视图模型,并为每个模型创建不同的映射。

3个回答

59

忽略(Ignore())功能仅适用于您从不映射的成员,因为这些成员也会在配置验证中被跳过。我尝试了几个选项,但似乎自定义值解析器之类的东西都行不通。

使用Condition()功能在条件为真时映射成员:

Mapper.CreateMap<CarViewModel, Car>()
 .ForMember(dest => dest.Code, opt => opt.Condition(source => source.Id != 0))

1
这个功能的状态如何?我们可以期待什么时候推出它? - mare
1
它在夜间版本中。您可以在teamcity.codebetter.com网站上找到它。 - Jimmy Bogard
8
我使用最新版本的AutoMapper,但是Skip方法不存在。 - VikciaR
我也看不到这个,如果能看到的话,对我正在做的事情会有很大帮助。 - Eman
4
这是一个条件。 - Jimmy Bogard
显示剩余4条评论

6

我遇到了类似的问题,虽然这个方法会用 null 覆盖现有的 dest.Code 值,但它可能是一个很好的起点:

AutoMapper.Mapper.CreateMap().ForMember(dest => dest.Code,config => config.MapFrom(source => source.Id != 0 ? null : source.Code));


不错的解决方法,我自己没有想到,但是Jimmy的方法仍然更好。 - alehro
不,Jimmy的答案并没有做到问题所要求的。它只是省略了一个未配置的字段的配置。因此,实质上它什么也没做。我不确定有人怎么会点赞那个所谓的解决方案。 - jwize
Jimmy的答案对我没用,这个可以。我认为是因为我试图将源映射到一个复杂对象,如果Id属性不等于0,就像这样:AutoMapper.Mapper.CreateMap().ForMember(dest => dest.MyObject,config => config.MapFrom(source => source.Id != 0 ? source : null)); - goku_da_master

0
这是有关条件映射的文档: http://docs.automapper.org/en/latest/Conditional-mapping.html 还有另一种方法叫做 PreCondition,它在某些场景下非常有用,因为它在映射过程中解析源值之前运行:
Mapper.PreCondition<CarViewModel, Car>()
 .ForMember(dest => dest.Code, opt => opt.Condition(source => source.Id == 0))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接