C# 使用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", &

在使用automapper时,我一直无法找到解决方案。 我的问题是我有一个源字典,我需要将源字典“映射”到一个键应该不同的新字典(基本上是“更改”源字典的键) 我想我可以用AutoMapper来做这个。。因此,我尝试了以下方法:

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) MappingExpression
2.FormMember[TMember](Expression
1 destinationMember,Action
1 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内核中对此有支持,遗憾的是我不能使用它