C# AutoMapper 映射如果不为空,否则自定义转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11555721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 18:17:13  来源:igfitidea点击:

AutoMapper Map If Not Null, Otherwise Custom Convert

c#automapper

提问by RPM1984

Here's my code:

这是我的代码:

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

Basically, "BarViewModel" has a parameterless ctor which sets up properties in the class.

基本上,“BarViewModel”有一个无参数的构造函数,它在类中设置属性。

So i'm trying to say to AutoMapper:

所以我想对 AutoMapper 说:

If the value is null, then use the ctor for the class. otherwise use the mapping you have in place

如果值为空,则使用类的构造函数。否则使用您现有的映射

The above is giving me a C# compiler error. And i'm guessing a cast wouldn't work either.

上面给了我一个 C# 编译器错误。而且我猜演员也行不通。

So is there a AutoMapper trick to do this?

那么是否有 AutoMapper 技巧可以做到这一点?

Worst case i could remove that mapping for that property, and just do:

最坏的情况是,我可以删除该属性的映射,然后执行以下操作:

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

But that's a tad ugly.

但这有点难看。

Ideas?

想法?

采纳答案by k0stya

You can use custom value resolver. The following should work:

您可以使用自定义值解析器。以下应该工作:

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

回答by devuxer

I don't get a compiler error for the following:

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

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

...so I'm wondering if the problem is not actually with your mapping?

...所以我想知道问题是否实际上不在于您的映射?

回答by Vijai

Now you can use .NullSubstitute()to replace NULL value to some custom value in Automapper, e.g.:

现在您可以使用.NullSubstitute()Automapper 将 NULL 值替换为某些自定义值,例如:

CreateMap<SMModel, VM_SMModel>()
                    .ForMember(d => d.myDate, o => o.NullSubstitute(new DateTime(2017,12,12)));

回答by spottedmahn

As of Automapper 8, ResolveUsingis no longer an optionbut inline Func's, IValueResolverand IMemberValueResolverare .

从 Automapper 8 开始,ResolveUsing不再是一个选项,而是 inlineFunc的,IValueResolver并且IMemberValueResolver是 。

Inline Func Example

内联函数示例

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 Example

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


There's some good documentation on Custom Value Resolvers here.

这里有一些关于自定义值解析器的很好的文档。

Working demo

工作演示