Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 自动映射来自多个源字段的条件映射_C#_Automapper - Fatal编程技术网

C# 自动映射来自多个源字段的条件映射

C# 自动映射来自多个源字段的条件映射,c#,automapper,C#,Automapper,我有一个如下所示的源类: public class Source { public Field[] Fields { get; set; } public Result[] Results { get; set; } } 并有一个目标类,如: public class Destination { public Value[] Values { get; set; } } 因此,我想从字段或结果映射到值,这取决于哪个值不为空(只有一个值) 我尝试了以下地图: Creat

我有一个如下所示的源类:

public class Source
{
    public Field[] Fields { get; set; }
    public Result[] Results { get; set; }
}
并有一个目标类,如:

public class Destination
{
    public Value[] Values { get; set; }
}
因此,我想从
字段
结果
映射到
,这取决于哪个值不为空(只有一个值)

我尝试了以下地图:

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);
            });
CreateMap();
CreateMap();
CreateMap()
.ForMember(d=>d.Values,opt=>
{
opt.predition(s=>s.Fields!=null);
opt.MapFrom(s=>s.Fields});
})
.ForMember(d=>d.Values,opt=>
{
opt.predition(s=>s.Results!=null);
opt.MapFrom(s=>s.Results);
});
唯一的问题是,如果最后一个
.ForMember
映射不满足条件,它会清除第一个映射的映射结果

我还考虑将其作为条件运算符:

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

但是很明显,它们是不同的类型,所以不要编译

如何根据条件从不同类型的源属性映射到单个属性


谢谢

有一个
ResolveUsing()
方法,允许您进行更复杂的绑定,您可以使用
IValueResolver
函数
。大概是这样的:

CreateMap<Source, Destination>()
    .ForMember(dest => dest.Values, mo => mo.ResolveUsing<ConditionalSourceValueResolver>());
CreateMap()
.FormMember(dest=>dest.Values,mo=>mo.ResolveUsing());
根据您的需要,值解析器可能如下所示:

 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);
        }
    }
公共类条件资源值解析程序:IValueResolver
{
公共值[]解析(源源、目标、值[]目标成员、解析上下文)
{
if(source.Fields==null)
返回context.Mapper.Map(source.Results);
其他的
返回context.Mapper.Map(source.Fields);
}
}

跟随@animalito_maquina

以下是以下内容的更新:

CreateMap()
.ForMember(dest=>dest.Values,mo=>mo.MapFrom());

为了节省您的时间,我们不支持ValueResolver,因为

太好了,谢谢!我认为我的一个问题是,在离开静态版本的mapper之后,我不确定如何在另一个map中实际绘制贴图。现在我知道我可以从上下文中理解它了。谢谢令人沮丧的是,当您发现自己在几乎所有映射中都使用了
resolve
,这导致了一些难看的代码,并让您怀疑使用AutoMapper是否比创建工厂更好
CreateMap<Source, Destination>()
    .ForMember(dest => dest.Values, mo => mo.MapFrom<ConditionalSourceValueResolver>());