简体   繁体   English

来自多个源字段的自动映射器条件 map

[英]Automapper conditional map from multiple source fields

I've got a source class like the following:我有一个源 class ,如下所示:

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

And have a destination class like:并有一个目的地 class 像:

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).所以我想从FieldsResultsValues的 map 取决于哪个不是 null (只有一个会有值)。

I tried the following map:我尝试了以下 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.唯一的问题是,如果最后一个.ForMember map 不满足从第一个 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?如何根据条件从不同类型的源属性 map 到单个属性?

Thanks谢谢

There is a ResolveUsing() method that allows you for more complex binding and you can use a IValueResolver or a Func .有一个ResolveUsing()方法允许您进行更复杂的绑定,您可以使用IValueResolverFunc 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);
        }
    }

Following @animalito_maquina answer .按照@animalito_maquina回答

Here is an update for 8.0 Upgrade :这是8.0 升级的更新:

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

And to save you time, ValueResolvers are not supported for Queryable Extensions为了节省您的时间,可查询扩展不支持ValueResolvers

ResolveUsing is not available, try this. ResolveUsing 不可用,试试这个。 It's working for me它对我有用

CreateMap<Source, Destination>()   
.ForMember(opt => opt.value, map => 
map.MapFrom((s, Ariel) => s.Fields != null ? s.Fields : s.Results));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM