C# 如何使用 Automapper 在两个枚举之间进行映射?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11265829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I map between two enums using Automapper?
提问by Jeffrey Lott
I have a public facing interface that I'm trying to map two different enumerations to each other. I tried to use the following code:
我有一个面向公众的界面,我试图将两个不同的枚举相互映射。我尝试使用以下代码:
Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>();
When that didn't work, I tried:
当那不起作用时,我尝试了:
Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>().ConvertUsing(x => (Common.ValidationResultType)((int)x));
But that doesn't seem to work either. Is there anyway to get automapper to handle this scenario?
但这似乎也不起作用。有没有办法让 automapper 来处理这种情况?
采纳答案by Jimmy Bogard
You don't need to do CreateMap for enum types. Just get rid of the CreateMap call and it should work, as long as the names and/or values match up between enum types.
您不需要为枚举类型执行 CreateMap。只要摆脱 CreateMap 调用,它应该可以工作,只要枚举类型之间的名称和/或值匹配。
回答by Trevor
Here's one possibility for making a conversion between two Enum types that both have different values, while still using AutoMapper. In my case, I needed to use AutoMapper because the Enum types were properties on other entities being converted by AutoMapper; using AutoMapper for these entities was a requirement.
这是在两个具有不同值的 Enum 类型之间进行转换的一种可能性,同时仍然使用 AutoMapper。就我而言,我需要使用 AutoMapper,因为 Enum 类型是 AutoMapper 转换的其他实体的属性;对这些实体使用 AutoMapper 是一项要求。
The first step is to setup the Mapper configuration like so:
第一步是像这样设置 Mapper 配置:
Mapper.CreateMap<EnumSrc, EnumDst>()
.ConstructUsing(EnumConversion.FromSrcToDst);
Calling .ConstructUsing(...)allows us to pass in our own method for making the conversion. The method for conversion is pretty straight forward:
调用.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;
}
}
}
We simply switchthrough the values of the source Enum and return the appropriate destination Enum value arbitrarily. AutoMapper takes care of the rest.
我们简单地switch通过源 Enum 的值并任意返回适当的目标 Enum 值。AutoMapper 负责其余的工作。
回答by Neil
The other answers here didn't work for me.
这里的其他答案对我不起作用。
You need to create a class that implements:
您需要创建一个实现的类:
ITypeConvertor<SourceType ,DestinationType>
So as an example
所以作为一个例子
Mapper.CreateMap<EnumType1.VatLevel, EnumType2.VatRateLevel>()
.ConvertUsing(new VatLevelConvertor());
And the class:
和班级:
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;
}
}
}
回答by Thorsten Hüglin
Alternatively to writing custom converters, just use ConvertUsing()
或者编写自定义转换器,只需使用 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;
}
});
回答by mesut
The Simplest Way I found that work for me is as below:
我发现对我有用的最简单方法如下:
My Enum is a nested in another class so I Use ForMember method and MapFrom as below:
我的 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));
The ProblemType and JudgmentType are Enums. And their related View Models are ProblemTypeViewModel and JudgmentTypeViewModel with same members as their related Models.
ProblemType 和 JudgmentType 是枚举。并且它们相关的视图模型是 ProblemTypeViewModel 和 JudgmentTypeViewModel 与它们的相关模型具有相同的成员。
Although I don't test, But I think below line should work for you:
虽然我不测试,但我认为下面这行应该适合你:
Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>()
.ForMember(m=> m, opt => opt.MapFrom(x=> (Common.ValidationResultType)(int)x);
Hope it Help.
希望它有帮助。
回答by MarioDS
I was trying to map between "equal" enums using Automapper, but unfortunately it didn't work. I suspect the problem is a difference in casing:
我试图使用 Automapper 在“相等”枚举之间进行映射,但不幸的是它不起作用。我怀疑问题是大小写不同:
public enum Foo {
val1,
val2
}
public enum Bar {
Val1,
Val2
}
Foois something auto-generated from an XSD, and the supplier sucks. Also there are thirty-something values and I didn't want to put a switchthat large anywhere for something so silly.
Foo是从 XSD 自动生成的东西,供应商很糟糕。还有三十多岁的价值观,我不想把switch这么大的地方放在这么愚蠢的地方。
The approach I took was to convert the source value to string and parse that as the destination value:
我采用的方法是将源值转换为字符串并将其解析为目标值:
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;
}
Of course, this only works if your enums only have differences in casing. You could make it more elaborate by cleaning up the input string (e.g. remove underscores etc.) or by adding stuff to it as required.
当然,这仅在您的枚举仅在大小写上有差异时才有效。您可以通过清理输入字符串(例如删除下划线等)或根据需要向其中添加内容来使其更加复杂。
回答by Dhanuka777
Just create a mapper for two Enums, that's it! Automapper will map by the either the matching value or index value of the Enum. (e.g. Draft -> Step1)
只需为两个枚举创建一个映射器,就是这样!Automapper 将通过 Enum 的匹配值或索引值进行映射。(例如草稿 -> 步骤 1)
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);
}
}
回答by Piotr Kwiatek
My Automapper works this way:
我的 Automapper 是这样工作的:
If I create a map:Automapper will match enums by value, even if name match perfectly.
如果我创建地图:Automapper 将按值匹配枚举,即使名称完全匹配。
If I do not create a map:Automapper will match enums by name.
如果我不创建地图:Automapper 将按名称匹配枚举。

