我有一个面向公众的界面,我试图将两个不同的枚举映射到彼此。我尝试使用以下代码:
Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>();
如果那不起作用,我试过了:
Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>().ConvertUsing(x => (Common.ValidationResultType)((int)x));
但这似乎也无济于事。反正有没有让automapper来处理这种情况?
答案 0 :(得分:49)
除了编写自定义转换器之外,只需使用ConvertUsing()
Mapper.CreateMap<EnumSrc, EnumDst>().ConvertUsing(value =>
{
switch(value)
{
case EnumSrc.Option1:
return EnumDst.Choice1;
case EnumSrc.Option2:
return EnumDst.Choice2;
case EnumSrc.Option3:
return EnumDst.Choice3;
default:
return EnumDst.None;
}
});
答案 1 :(得分:37)
您不需要为枚举类型执行CreateMap。只要在枚举类型之间匹配名称和/或值,就可以去除CreateMap调用,它应该可以工作。
答案 2 :(得分:10)
我的Automapper以这种方式工作:
如果我创建地图: 即使名称完全匹配,Automapper也会按值匹配枚举。
如果我不创建地图: Automapper将按名称匹配枚举。
答案 3 :(得分:4)
最简单的方法我发现为我工作如下:
My Enum是一个嵌套在另一个类中,所以我使用ForMember方法和MapFrom如下:
Mapper.CreateMap<ProblematicCustomer, ProblematicCustomerViewModel>()
.ForMember(m=> m.ProblemType, opt=> opt.MapFrom(x=> (ProblemTypeViewModel)(int)x.ProblemType))
.ForMember(m=> m.JudgmentType, opt=> opt.MapFrom(x=> (JudgmentTypeViewModel)(int)x.JudgmentType));
ProblemType和JudgmentType是枚举。他们的相关视图模型是ProblemTypeViewModel和JudgmentTypeViewModel,其成员与相关模型相同。
虽然我没有测试,但我认为下面的行应该适合你:
Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>()
.ForMember(m=> m, opt => opt.MapFrom(x=> (Common.ValidationResultType)(int)x);
希望有所帮助。
答案 4 :(得分:3)
这里有一种在两个枚举类型之间进行转换的可能性,它们都具有不同的值,同时仍然使用AutoMapper。在我的例子中,我需要使用AutoMapper,因为Enum类型是AutoMapper转换的其他实体的属性;使用AutoMapper是必需的。
第一步是设置Mapper配置,如下所示:
Mapper.CreateMap<EnumSrc, EnumDst>()
.ConstructUsing(EnumConversion.FromSrcToDst);
调用.ConstructUsing(...)
允许我们传递自己的方法进行转换。转换方法非常简单:
public class EnumConversion
{
internal static EnumDst FromSrcToDst(ResolutionContext arg)
{
EnumSrc value = (EnumSrc)arg.SourceValue;
switch(value)
{
case EnumSrc.Option1:
return EnumDst.Choice1;
case EnumSrc.Option2:
return EnumDst.Choice2;
case EnumSrc.Option3:
return EnumDst.Choice3;
default:
return EnumDst.None;
}
}
}
我们只需通过源Enum的值switch
并任意返回相应的目标枚举值。 AutoMapper负责其余部分。
答案 5 :(得分:3)
这里的其他答案对我没用。
您需要创建一个实现的类:
ITypeConvertor<SourceType ,DestinationType>
以此为例
Mapper.CreateMap<EnumType1.VatLevel, EnumType2.VatRateLevel>()
.ConvertUsing(new VatLevelConvertor());
上课:
internal class VatLevelConvertor : ITypeConverter<EnumType1.VatLevel, EnumType2.VatRateLevel>
{
public EnumType2.VatRateLevel Convert(ResolutionContext context)
{
EnumType1.VatLevel value = (EnumType1.VatLevel)context.SourceValue;
switch (value)
{
case EnumType1.VatLevel.Standard:
return EnumType2.VatRateLevel.Normal;
case EnumType1.VatLevel.Reduced:
return EnumType2.VatRateLevel.Lower;
case EnumType1.VatLevel.SuperReduced:
return EnumType2.VatRateLevel.Other;
default:
return EnumType2.VatRateLevel.Other;
}
}
}
答案 6 :(得分:3)
只需为两个枚举创建一个映射器,就是这样! Automapper将根据Enum的匹配值或索引值进行映射。 (例如草案 - &gt; Step1)
public enum SourceStatus
{
Draft,
Submitted,
Deleted
}
public enum DestinationStatus
{
Step1,
Step2,
Step3
}
public class SourceObj
{
public SourceStatus Status { get; set; }
}
public class DestinationObj
{
public DestinationStatus Status { get; set; }
}
class Program
{
static void Main(string[] args)
{
//Static APi style - this is obsolete now. From Version 5.0 onwards this will be removed.
SourceObj mySrcObj = new SourceObj();
mySrcObj.Status = SourceStatus.Deleted;
Mapper.CreateMap<SourceStatus, DestinationStatus>();
Mapper.CreateMap<SourceObj, DestinationObj>();
DestinationObj myDestObj = Mapper.Map<SourceObj, DestinationObj>(mySrcObj);
//New way of doing it
SourceObj mySrcObj2 = new SourceObj();
mySrcObj2.Status = SourceStatus.Draft;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SourceObj, DestinationObj>();
});
IMapper mapper = config.CreateMapper();
var source = new SourceObj();
var dest = mapper.Map<SourceObj, DestinationObj>(source);
}
}
答案 7 :(得分:2)
我试图使用Automapper在“相等”的枚举之间进行映射,但不幸的是它没有用。我怀疑问题是套管的差异:
public enum Foo {
val1,
val2
}
public enum Bar {
Val1,
Val2
}
Foo
是从XSD自动生成的,供应商很糟糕。还有三十多个值,而且我不想把switch
那么大的东西放在任何地方,因为它太傻了。
我采用的方法是将源值转换为字符串并将其解析为目标值:
static Foo ConvertEnum(Bar source)
{
Foo result;
var parsed = Enum.TryParse(source.ToString().ToLowerInvariant(), true, out result);
if(!parsed)
// throw or return default value
throw new ArgumentOutOfRangeException("source", source, "Unknown source value");
return result;
}
当然,这只适用于你的枚举只有套管差异的情况。您可以通过清理输入字符串(例如删除下划线等)或根据需要添加内容来使其更精细。
答案 8 :(得分:0)
我知道这个问题很老,但如果像我这样的人路过这里...
从 AutoMapper documentation 开始,现在有一个 AutoMapper.Extensions.EnumMapping Nuget package 提供了一种简单的方法。
引自 AutoMapper 文档:
public enum Source
{
Default = 0,
First = 1,
Second = 2
}
public enum Destination
{
Default = 0,
Second = 2
}
internal class YourProfile : Profile
{
public YourProfile()
{
CreateMap<Source, Destination>()
.ConvertUsingEnumMapping(opt => opt
// optional: .MapByValue() or MapByName(), without configuration MapByValue is used
.MapValue(Source.First, Destination.Default)
)
.ReverseMap(); // to support Destination to Source mapping, including custom mappings of ConvertUsingEnumMapping
}
}