使用AutoMapper映射枚举数组并剔除无对应值元素的问题
如何用AutoMapper将枚举数组映射到另一个枚举数组并过滤无对应映射的元素
我需要把一个枚举数组映射到另一个枚举数组,其中目标枚举的取值更少,同时要移除那些没有对应映射关系的元素。
枚举定义
public enum Person1ColoursEnum { BlueColour = 1, RedColour = 2 } public enum Person2ColoursEnum { Blue = 1, Red = 2, Green = 3, Yellow = 4, Pink = 5 }
待映射代码
var person2Colours = new[] { Person2ColoursEnum.Blue, Person2ColoursEnum.Red, Person2ColoursEnum.Yellow }; var favColours = mapper.Map<Person1ColoursEnum[]>(person2Colours);
期望结果
[BlueColour, RedColour]
当前问题
我用下面的配置映射后,得到的结果是[BlueColour, RedColour, 0](原数组第三个元素被转成默认值0),达不到预期:
CreateMap<Person2ColoursEnum, Person1ColoursEnum>() .ConvertUsingEnumMapping(opt => opt .MapValue(Person2ColoursEnum.Blue, Person1ColoursEnum.BlueColour ) .MapValue(Person2ColoursEnum.Red, Person1ColoursEnum.RedColour ) .MapValue(Person2ColoursEnum.Green, default) .MapValue(Person2ColoursEnum.Yellow, default) .MapValue(Person2ColoursEnum.Pink, default) );
解决方案
方案1:映射后直接过滤(最简单)
映射完成后用LINQ过滤掉默认值元素,直接得到目标数组:
var favColours = mapper.Map<Person1ColoursEnum[]>(person2Colours) .Where(colour => colour != default(Person1ColoursEnum)) .ToArray();
方案2:配置数组的自定义映射规则(在AutoMapper内部完成)
如果不想额外写过滤代码,可以直接配置数组类型的映射规则,让AutoMapper自动处理过滤:
// 保留原有的单个枚举映射配置 CreateMap<Person2ColoursEnum, Person1ColoursEnum>() .ConvertUsingEnumMapping(opt => opt .MapValue(Person2ColoursEnum.Blue, Person1ColoursEnum.BlueColour) .MapValue(Person2ColoursEnum.Red, Person1ColoursEnum.RedColour) .MapValue(Person2ColoursEnum.Green, default) .MapValue(Person2ColoursEnum.Yellow, default) .MapValue(Person2ColoursEnum.Pink, default)); // 新增数组映射规则,自动过滤无效元素 CreateMap<Person2ColoursEnum[], Person1ColoursEnum[]>() .ConvertUsing((source, _, context) => source.Select(item => context.Mapper.Map<Person1ColoursEnum>(item)) .Where(colour => colour != default(Person1ColoursEnum)) .ToArray());
之后直接调用mapper.Map<Person1ColoursEnum[]>(person2Colours)就能得到预期结果。
方案3:用可空枚举中转(更安全,避免默认值冲突)
如果目标枚举Person1ColoursEnum以后可能会定义值为0的枚举项,用default判断就会出错。这种情况可以先映射到可空枚举,再过滤null值:
// 配置到可空枚举的映射,无对应关系的返回null CreateMap<Person2ColoursEnum, Person1ColoursEnum?>() .ConvertUsingEnumMapping(opt => opt .MapValue(Person2ColoursEnum.Blue, Person1ColoursEnum.BlueColour) .MapValue(Person2ColoursEnum.Red, Person1ColoursEnum.RedColour) .MapValue(Person2ColoursEnum.Green, (Person1ColoursEnum?)null) .MapValue(Person2ColoursEnum.Yellow, (Person1ColoursEnum?)null) .MapValue(Person2ColoursEnum.Pink, (Person1ColoursEnum?)null)); // 配置数组映射:转成可空数组后过滤null,再转成非空数组 CreateMap<Person2ColoursEnum[], Person1ColoursEnum[]>() .ConvertUsing((source, _, context) => source.Select(item => context.Mapper.Map<Person1ColoursEnum?>(item)) .Where(colour => colour.HasValue) .Select(colour => colour.Value) .ToArray());
这种方式完全避免了默认值判断的风险,适合枚举可能扩展的场景。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

