如何使用自动映射器映射使用不同大小写的2个枚举

时间:2019-02-05 12:40:11

标签: enums automapper case-insensitive

我有很多枚举要保留所有必须映射到另一个完全没有标准的系统(大写,无大写,帕斯卡,骆驼)的枚举。我找不到自动映射器标志来告诉它忽略枚举的大小写。我可以为每个枚举使用一个custome转换器,但由于数量太多,我希望使用通用转换器。

这里的一些答案暗示自动映射器已经做到了。我没有从测试中得到。

如果我有这些枚举:

public enum AllCaps
{
    VALUE1,
    VALUE2,
    VALUE3
}

public enum NoCaps
{
    value1,
    value2,
    value3
}

public enum MixedCaps
{
    Value1,
    Value2,
    Value3
}

这些地图:

CreateMap<AllCaps, NoCaps>();
CreateMap<AllCaps, MixedCaps>();
CreateMap<NoCaps, AllCaps>();
CreateMap<NoCaps, MixedCaps>();
CreateMap<MixedCaps, AllCaps>();
CreateMap<MixedCaps, NoCaps>();

此代码:

var vAllCaps = new AllCaps();
var vNoCaps = new NoCaps();
var vMixedCaps = new MixedCaps();

vAllCaps = AllCaps.VALUE2;
vNoCaps = NoCaps.value2;
vMixedCaps = MixedCaps.Value2;

var AllCapsToNoCaps = Mapper.Map<AllCaps, NoCaps>(vAllCaps);
var AllCapsToMixedCaps = Mapper.Map<AllCaps, MixedCaps>(vAllCaps);
var NoCapsToAllCaps = Mapper.Map<NoCaps, AllCaps>(vNoCaps);
var NoCapsToMixedCaps = Mapper.Map<NoCaps, MixedCaps>(vNoCaps);
var MixedCapsToAllCaps = Mapper.Map<MixedCaps, AllCaps>(vMixedCaps);
var MixedCapsToNoCaps = Mapper.Map<MixedCaps, NoCaps>(vMixedCaps);

我所有映射变量的结果均为VALUE1,value1或Value1,而不是预期的VALUE2,value2或Value2。

1 个答案:

答案 0 :(得分:1)

Automapper 自动在枚举之间进行不区分大小写的映射。 不需要 CreateMap<EnumSource, EnumDest>() 调用枚举。

有一些细节值得一提:

  • 嵌入在映射类型中的枚举值不区分大小写
  • configuration.AssertConfigurationIsValid() 不检查目标值是否可用于所有源值
  • 如果目标枚举中不存在源值,则采用数值

AutoMapper.Extensions.EnumMapping 可以验证枚举映射,但此扩展会进行区分大小写的检查。简单的枚举到枚举的映射并不是真正需要的。

可以添加自定义验证来检查有效的枚举映射

示例代码:

config.Advanced.Validator(context =>
            {
                if (context.TypeMap != null)
                {
                    foreach (var memberMap in context.TypeMap.MemberMaps)
                    {
                        if (memberMap.SourceType.IsEnum && memberMap.DestinationType.IsEnum)
                        {
                            var hasMappingError = false;
                            var sourceEnumValue = Enum.GetValues(memberMap.SourceType).Cast<object>()
                                .Select(x => x.ToString().ToLowerInvariant()).ToList();
                            var targetEnumValues = Enum.GetValues(memberMap.DestinationType).Cast<object>()
                                .Select(x => x.ToString().ToLowerInvariant()).ToList();

                            var messageBuilder =
                                new StringBuilder(
                                    $"Missing enum mapping from {memberMap.SourceType.FullName} to {memberMap.DestinationType.FullName}");

                            messageBuilder.AppendLine();
                            messageBuilder.AppendLine("The following source values are not mapped:");

                            foreach (var sourceValue in sourceEnumValue)
                            {
                                if (!targetEnumValues.Contains(sourceValue))
                                {
                                    hasMappingError = true;
                                    messageBuilder.AppendLine($" - {sourceValue}");
                                }
                            }

                            if (hasMappingError)
                            {
                                throw new AutoMapperConfigurationException(messageBuilder.ToString());
                            }
                        }
                    }
                }
            });