使用AutoMapper映射字典

时间:2011-05-13 16:45:09

标签: automapper

鉴于这些类,我如何映射它们的字典?

public class TestClass
{
    public string Name { get; set; }
}

public class TestClassDto
{
    public string Name { get; set; }
}


Mapper.CreateMap<TestClass, TestClassDto>();
Mapper.CreateMap<Dictionary<string, TestClass>, 
                  Dictionary<string, TestClassDto>>();

var testDict = new Dictionary<string, TestClass>();
var testValue = new TestClass() {Name = "value1"};
testDict.Add("key1", testValue);

var mappedValue = Mapper.Map<TestClass, TestClassDto>(testValue);

var mappedDict = Mapper.Map<Dictionary<string, TestClass>, 
                            Dictionary<string, TestClassDto>>(testDict);

在这种情况下映射其中一个,mappedValue,工作正常。

映射它们的字典最终没有目标对象中的条目。

我在做什么?

2 个答案:

答案 0 :(得分:16)

您遇到的问题是因为AutoMapper正在努力映射字典的内容。你必须考虑它的存储 - 在这种情况下 KeyValuePairs

如果你尝试为KeyValuePair组合创建一个mapper,你会很快发现你不能直接因为 Key属性没有setter

AutoMapper通过允许您使用构造函数进行映射来解决这个问题。

/* Create the map for the base object - be explicit for good readability */
Mapper.CreateMap<TestClass, TestClassDto>()
      .ForMember( x => x.Name, o => o.MapFrom( y => y.Name ) );

/* Create the map using construct using rather than ForMember */
Mapper.CreateMap<KeyValuePair<string, TestClass>, KeyValuePair<string, TestClassDto>>()
      .ConstructUsing( x => new KeyValuePair<string, TestClassDto>( x.Key, 
                                                                    x.Value.MapTo<TestClassDto>() ) );

var testDict = new Dictionary<string, TestClass>();
var testValue = new TestClass()
{
    Name = "value1"
};
testDict.Add( "key1", testValue );

/* Mapped Dict will have your new KeyValuePair in there */
var mappedDict = Mapper.Map<Dictionary<string, TestClass>,
Dictionary<string, TestClassDto>>( testDict );

答案 1 :(得分:2)

AutoMapper进行了一些更改,因此看起来更像:

CreateMap<Thing, ThingDto>()
     .ReverseMap();
CreateMap<Thing, KeyValuePair<int, ThingDto>>()
     .ConstructUsing((t, ctx) => new KeyValuePair<int, ThingDto>(t.id, ctx.Mapper.Map<ThingDto>(t)));