AutoMapper Map如果不为空,否则自定义转换

时间:2012-07-19 07:17:12

标签: c# automapper

这是我的代码:

Mapper.CreateMap<Foo, Foo2>()
   .ForMember(dest => dest.Bar, opt => opt.MapFrom(src => src.Bar == null ? new BarViewModel() : src.Bar))

基本上,“BarViewModel”有一个无参数的ctor,可以在类中设置属性。

所以我想对AutoMapper说:

  

如果值为null,则使用ctor作为类。否则使用你现有的映射

以上是给我一个C#编译错误。我猜测演员阵容也不会奏效。

那么有一个AutoMapper技巧吗?

最糟糕的情况是我可以删除该属性的映射,只需执行:

var mapped = Mapper.Map<Foo,Foo2>(src);
if (mapped.Bar == null) mapped.Bar = new BarViewModel();

但那有点难看。

想法?

4 个答案:

答案 0 :(得分:36)

您可以使用custom value resolver。以下应该有效:

Mapper.CreateMap<Foo, Foo2>()
   .ForMember(dest => dest.Bar, opt => opt.ResolveUsing(src => src.Bar == null ? new Bar() : Mapper.Map<Bar,Bar2>(src.Bar)))

答案 1 :(得分:9)

现在,您可以使用from datetime import datetime now = datetime.utcnow() then = datetime.utcfromtimestamp(timestamp_in_millis * 1e-3) if now > then: print("expired") 将NULL值替换为Automapper中的某个自定义值,例如:

.NullSubstitute()

答案 2 :(得分:3)

我没有收到以下的编译器错误:

public class Foo
{
    public Bar Bar { get; set; }
}

public class Foo2
{
    public Bar Bar { get; set; }
}

public class Bar
{
    public int Id { get; set; }

    public Bar()
    {
        Id = 3;
    }
}

CreateMap<Foo, Foo2>()
    .ForMember(
        dest => dest.Bar,
        opt => opt.MapFrom(src => src.Bar == null ? new Bar() : src.Bar));

...所以我想知道问题是不是你的映射?

答案 3 :(得分:2)

从Automapper 8开始,ResolveUsing is no longer an option,但内联FuncIValueResolverIMemberValueResolver是。

内联函数示例

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<Foo, FooViewModel>()
       .ForMember(dest => dest.BarViewModel,
                  opt  => opt.MapFrom((src, dest) =>
                  {
                     if (src.Bar == null)
                        return new BarViewModel ();

                     return Mapper.Map<Bar, BarViewModel>(src.Bar);
                  }));

    cfg.CreateMap<Bar, BarViewModel>();
});

IMemberValueResolver示例

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<Foo, FooViewModel>()
       .ForMember(dest => dest.BarViewModel,
                  opt  => opt.MapFrom<NullBarResolver, Bar>(src => src.Bar));

    cfg.CreateMap<Bar, BarViewModel>();
});

public class NullBarResolver : IMemberValueResolver<object, object, Bar, BarViewModel>
{
    public BarViewModel Resolve(object source, object destination, Bar sourceMember,
                                BarViewModel destMember, ResolutionContext context)
    {
        if (sourceMember == null)
            return new BarViewModel();

        return Mapper.Map(sourceMember, destMember);
    }
}

Custom Value Resolvers here上有一些不错的文档。

Working demo