使用自动映射器将一本词典映射到另一本词典

时间:2020-09-14 23:16:20

标签: c# dictionary automapper asp.net-core-3.1

使用自动映射器时,我无法找到解决方案。 我的问题是我有一个源词典,并且需要将源词典“映射”到一个新的词典,在该词典中键应该是不同的(基本上是“更改”源词典的键) 我认为我可以为此使用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>
    {
    }

创建两个类只是为了确保在MapperConfiguration移至Profile且Profile被“全局”加载后,我们不只是映射应用程序中的所有字典。

但是..以上结果最终出现以下错误:

消息: 测试方法DictionaryMapperTest.MapDictionary.CanMapDictionaryDictionaryUsingAutoMapper 抛出异常: AutoMapper.AutoMapperConfigurationException:仅成员的自定义配置支持 类型。堆栈跟踪: ReflectionHelper.FindProperty(LambdaExpression lambdaExpression) MappingExpression 2.ForMember[TMember](Expression 1个目标成员,操作1 memberOptions) <>c.<CanMapDictionaryDictionaryUsingAutoMapper>b__1_0(IMapperConfigurationExpression cfg) line 23 MapperConfiguration.Build(Action 1个配置) MapperConfiguration.ctor(操作1配置) MapDictionary.CanMapDictionaryDictionaryUsingAutoMapper()第20行

我错过了什么吗?有没有人有更好的解决方案来完成我试图达到的“映射”?我有点卡住..并且由于我在应用程序中的所有其他映射都利用了AutoMapper,因此能够保持一致并将其全部保存在一个地方会很好。

1 个答案:

答案 0 :(得分:1)

免责声明:我不建议使用字典来存储这些值。具有属性(FirstNameLastNameAge)的类比以属性名称作为键的字典有意义。

说过:

您已定义了Source的{​​{1}}和Destination。如果您想要一个类,它将使用相同的值但键不同的方式将Dictionary<string, object>映射到Source,则该类可以这样做:

Destination

我使用了一些额外的行和变量,以便更轻松地了解正在发生的事情。

它将一个键到另一个键的映射存储在字典中。给定源,它将查看字典中的所有键。这些键是“源”键-即源字典中的键。

对于每个键,如果源词典中都有该键,那么它将在public class DictionaryMapper { private readonly static Dictionary<string, string> keyMap; static DictionaryMapper() { keyMap = new Dictionary<string, string> { { "Name", "FirstName" }, { "LastName", "Surname" }, { "Years", "Age" } }; } public Destination MapSourceToDestination(Source source) { var destination = new Destination(); foreach (string sourceKey in keyMap.Keys) { if (source.ContainsKey(sourceKey)) { var destinationKey = keyMap[sourceKey]; var destinationValue = source[sourceKey]; destination.Add(destinationKey, destinationValue); } } return destination; } } 词典中查找目标键,并使用它从中检索到的键将源值添加到目标词典中keyMap

输出为keyMap字典,其值与源字典相同,但具有新的键。

即使使用Automapper可以做到这一点,您也可能会更容易阅读。

该类及其所有方法可以是Destination。我不知道您如何使用它,所以请根据您的需要进行调整。