Automapper conditional map from multiple source fields

南笙酒味 提交于 2021-01-20 06:59:52

问题


I've got a source class like the following:

public class Source
{
    public Field[] Fields { get; set; }
    public Result[] Results { get; set; }
}

And have a destination class like:

public class Destination
{
    public Value[] Values { get; set; }
}

So I want to map from EITHER Fields or Results to Values depending on which one is not null (only one will ever have a value).

I tried the following map:

CreateMap<Fields, Values>();                
CreateMap<Results, Values>();                

CreateMap<Source, Destination>()                
            .ForMember(d => d.Values, opt =>
            {
                opt.PreCondition(s => s.Fields != null);
                opt.MapFrom(s => s.Fields });
            })
            .ForMember(d => d.Values, opt =>
            {
                opt.PreCondition(s => s.Results != null);
                opt.MapFrom(s => s.Results);
            });

Only issue with this is that it looks if the last .ForMember map doesn't meet the condition it wipes out the mapping result from the first map.

I also thought about doing it as a conditional operator:

opt => opt.MapFrom(s => s.Fields != null ? s.Fields : s.Results)

But obviously they are different types so don't compile.

How can I map to a single property from source properties of different types based on a condition?

Thanks


回答1:


There is a ResolveUsing() method that allows you for more complex binding and you can use a IValueResolver or a Func. Something like this:

CreateMap<Source, Destination>()
    .ForMember(dest => dest.Values, mo => mo.ResolveUsing<ConditionalSourceValueResolver>());

And the value resolver depending on your needs may look like:

 public class ConditionalSourceValueResolver : IValueResolver<Source, Destination, Value[]>
    {
        public Value[] Resolve(Source source, Destination destination, Value[] destMember, ResolutionContext context)
        {
            if (source.Fields == null)
                return context.Mapper.Map<Value[]>(source.Results);
            else
                return context.Mapper.Map<Value[]>(source.Fields);
        }
    }



回答2:


Following @animalito_maquina answer.

Here is an update for 8.0 Upgrade:

CreateMap<Source, Destination>()
    .ForMember(dest => dest.Values, mo => mo.MapFrom<ConditionalSourceValueResolver>());

And to save you time, ValueResolvers are not supported for Queryable Extensions



来源:https://stackoverflow.com/questions/44969796/automapper-conditional-map-from-multiple-source-fields

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!