C# 使用automapper从一个字典映射到另一个字典
在使用automapper时,我一直无法找到解决方案。 我的问题是我有一个源字典,我需要将源字典“映射”到一个键应该不同的新字典(基本上是“更改”源字典的键) 我想我可以用AutoMapper来做这个。。因此,我尝试了以下方法:C# 使用automapper从一个字典映射到另一个字典,c#,dictionary,automapper,asp.net-core-3.1,C#,Dictionary,Automapper,Asp.net Core 3.1,在使用automapper时,我一直无法找到解决方案。 我的问题是我有一个源字典,我需要将源字典“映射”到一个键应该不同的新字典(基本上是“更改”源字典的键) 我想我可以用AutoMapper来做这个。。因此,我尝试了以下方法: private Source source = new Source { { "Name", "Frodo" }, { "LastName", &
private Source source = new Source
{
{ "Name", "Frodo" },
{ "LastName", "Bagginz" },
{ "Years", 32 }
};
[TestMethod]
public void CanMapDictionaryDictionaryUsingAutoMapper()
{
var configuration = new MapperConfiguration
(
cfg =>
cfg.CreateMap<Source, Destination>()
.ForMember(m => m["FirstName"], o => o.MapFrom(s => s["Name"]))
.ForMember(m => m["Surname"], o => o.MapFrom(s => s["LastName"]))
.ForMember(m => m["Age"], o => o.MapFrom(s => s["Years"]))
);
var mapper = configuration.CreateMapper();
var result = mapper.Map<Destination>(source);
Assert.IsTrue(result.ContainsKey("FirstName"));
Assert.IsTrue(result.ContainsValue("FirstName"));
Assert.IsTrue(result.ContainsKey("Surname"));
Assert.IsTrue(result.ContainsValue("Surname"));
Assert.IsTrue(result.ContainsKey("Age"));
Assert.IsTrue(result.ContainsValue("Age"));
}
}
public class Source : Dictionary<string, object>
{
}
public class Destination : Dictionary<string, object>
{
}
private Source=新源
{
{“名字”,“佛罗多”},
{“LastName”,“Bagginz”},
{“年”,32}
};
[测试方法]
public void CanmapDictionaryDictionaryYusingAutomapper()的
{
var配置=新的MapperConfiguration
(
cfg=>
cfg.CreateMap()
.ForMember(m=>m[“FirstName”],o=>o.MapFrom(s=>s[“Name”]))
.ForMember(m=>m[“姓氏”],o=>o.MapFrom(s=>s[“姓氏”]))
.ForMember(m=>m[“Age”],o=>o.MapFrom(s=>s[“Years”]))
);
var mapper=configuration.CreateMapper();
var result=mapper.Map(源);
Assert.IsTrue(result.ContainsKey(“名字”));
Assert.IsTrue(result.ContainsValue(“FirstName”);
Assert.IsTrue(result.ContainsKey(“姓氏”);
Assert.IsTrue(result.ContainsValue(“姓氏”));
Assert.IsTrue(result.ContainsKey(“年龄”));
Assert.IsTrue(result.ContainsValue(“年龄”));
}
}
公共类来源:字典
{
}
公共类目的地:字典
{
}
创建这两个类只是为了确保在MapperConfiguration被移动到配置文件并且配置文件被“全局”加载后,我们不会只映射应用程序中的所有字典
然而。。上述操作会导致以下错误:
信息:
测试方法DictionaryMapperTest.MapDictionary.CanMapDictionaryDictionaryDictionaryUISingautomaper
引发异常:
AutoMapper.AutoMapperConfigurationException:成员的自定义配置仅支持应用程序上的顶级单个成员
类型。堆栈跟踪:
ReflectionHelper.FindProperty(LambdaExpression LambdaExpression)
MappingExpression2.FormMember[TMember](Expression
1 destinationMember,Action1 memberOptions)c.b_uu1_u0(IMapperConfigurationExpression cfg)第23行MapperConfiguration.Build(Action
1 configure)
MapperConfiguration.ctor(操作'1配置)
MapDictionary.CanMapDictionaryDictionaryUISingautomaper()第20行
我错过什么了吗?有没有人有更好的解决方案来完成我试图在上面实现的那种“映射”?我有点卡住了。。由于我在应用程序中的所有其他映射都使用AutoMapper,因此能够保持一致并将所有映射保存在一个位置将是一件好事。免责声明:我不建议使用字典来存储这些值。具有属性(
FirstName
,LastName
,Age
)的类比具有属性名称作为键的字典更有意义
尽管如此:
您已经定义了源
和目标
,它们都是字典
。如果您想要一个将源
映射到目标
且具有相同值但不同键的类,则该类将执行以下操作:
公共类字典映射器
{
私有只读静态字典密钥映射;
静态字典映射()
{
keyMap=新字典
{
{“名字”,“名字”},
{“姓氏”、“姓氏”},
{“年”、“年龄”}
};
}
公共目标映射SourceToDestination(源)
{
var destination=新目的地();
foreach(keyMap.Keys中的字符串sourceKey)
{
if(source.ContainsKey(sourceKey))
{
var destinationKey=keyMap[sourceKey];
var destinationValue=source[sourceKey];
destination.Add(destinationKey,destinationValue);
}
}
返回目的地;
}
}
我使用了一些额外的行和变量,以便更容易地看到发生了什么
它将一个键到另一个键的映射存储在字典中。给定源代码,它会查看字典中的所有键。这些键是“源”键,即源字典中的键
对于每个键,如果源字典具有该键,那么它将在keyMap
字典中查找目标键,并使用从keyMap
检索的键将源字典中的值添加到目标字典中
输出是一个目标
字典,其值与源字典相同,但具有新的键
即使这可以通过Automapper完成,您可能会发现这更容易阅读
该类及其所有方法可以是
静态的
。我不知道您是如何使用它的,所以请根据您的需要进行调整。目的是我有一个来自请求主体的Json,属性名称需要映射到其他名称,以便稍后可以将tve Json发送到其他系统。不过,我可以通过简单地使用强类型对象和自动映射来实现这一点。。Json应该作为补丁方法发送,如果我用未设置的属性序列化了一个强类型对象,那么在序列化的Json中会得到默认值。在一个补丁请求中,它实际上会用默认值更新我的资源,这就是为什么我不能使用强类型的类/对象..并且只是添加到上面。。值为Bull的Json属性实际上会将系统中的属性设置为null。虽然发送的Json中不存在该属性的值,但系统不会更改该属性值。我知道也有JsonPatch,它是这样做的一种格式,并且在asp.net/.net内核中对此有支持,遗憾的是我不能使用它