我正在尝试用字典在这两个类之间进行映射
class HouseFrom
{
public IDictionary<string, PersonFrom> Items { get; set; } = new Dictionary<string, PersonFrom>();
}
class PersonFrom
{
public int Age { get; set; }
}
class HouseTo
{
public IDictionary<string, PersonTo> People { get; set; } = new Dictionary<string, PersonTo>();
}
class PersonTo
{
public string Name { get; set; }
public int Age { get; set; }
}
我通过几种方法使用automapper 10.1.0: 例如(也尝试了其他变体):
cfg.CreateMap<HouseFrom, HouseTo>().ForMember(t => t.People, opt => opt.MapFrom(t => t.Items));
cfg.CreateMap<KeyValuePair<string, PersonFrom>, KeyValuePair<string, PersonTo>>()
.ConstructUsing((t, c) => KeyValuePair.Create(t.Key, c.Mapper.Map<PersonTo>(t.Value)))
.AfterMap((b, a) => { a.Value.Name = a.Key; Console.WriteLine(a.Value.Name); });
and
cfg.CreateMap<HouseFrom, HouseTo>().ForMember(t => t.People, opt => opt.MapFrom(t => t.Items));
cfg.CreateMap<IDictionary<string, PersonFrom>, IDictionary<string, PersonTo>>()
.ConstructUsing((t, c) => t.Select(t => new PersonTo { Age = t.Value.Age, Name = t.Key }).ToDictionary(k => k.Name, v => v));
and
cfg.CreateMap<HouseFrom, HouseTo>().ForMember(t => t.People, opt => opt.MapFrom(t => t.Items));
cfg.CreateMap<KeyValuePair<string, PersonFrom>, KeyValuePair<string, PersonTo>>()
.ConstructUsing((c, ctx) => KeyValuePair.Create(c.Key, ctx.Mapper.Map<PersonTo>(c)))
.ForMember(t => t.Value, opt => opt.Ignore())
.ForMember(t => t.Key, opt => opt.Ignore());
但是我要么得到此异常:
Mutating a key collection derived from a dictionary is not allowed.
或该映射不会填充 PersonTo 的 Name 参数,因此为 null 。
感谢您在此问题上的帮助。
更新: 我尝试了以下映射,但都没有成功:
new MapperConfiguration(cfg =>
{
cfg.CreateMap<HouseFrom, HouseTo>()
.ForMember(t => t.People, opt => opt.MapFrom(t => t.Items));
cfg.CreateMap<KeyValuePair<string, PersonFrom>, KeyValuePair<string, PersonTo>>()
.ConstructUsing((t, c) => KeyValuePair.Create(t.Key, c.Mapper.Map<PersonTo>(t)));
cfg.CreateMap<KeyValuePair<string, PersonFrom>, PersonTo>()
.ForMember(src => src.Age, opt => opt.MapFrom(t => t.Value.Age))
.ForMember(src => src.Name, opt => opt.MapFrom(t => t.Key));
});
//Throws : Mutating a key collection derived from a dictionary is not allowed.
和
new MapperConfiguration(cfg =>
{
cfg.CreateMap<HouseFrom, HouseTo>()
.ForMember(t => t.People, opt => opt.MapFrom(t => t.Items));
cfg.CreateMap<PersonFrom, PersonTo>();
cfg.CreateMap<KeyValuePair<string, PersonFrom>, KeyValuePair<string, PersonTo>>()
.ConstructUsing((t, c) => KeyValuePair.Create(t.Key, c.Mapper.Map<PersonTo>(t.Value)))
.AfterMap((b, a) => { a.Value.Name = a.Key; });
});
//Return NULL for Name
和
new MapperConfiguration(cfg =>
{
cfg.CreateMap<HouseFrom, HouseTo>()
.ForMember(t => t.People, opt => opt.MapFrom(t => t.Items));
cfg.CreateMap<IDictionary<string, PersonFrom>, IDictionary<string, PersonTo>>()
.ConstructUsing((t, c) => t.Select(t => new PersonTo { Age = t.Value.Age, Name = t.Key }).ToDictionary(k => k.Name, v => v));
});
//Throws : Mutating a key collection derived from a dictionary is not allowed.
解决方案:
return new MapperConfiguration(cfg =>
{
cfg.CreateMap<HouseFrom, HouseTo>()
.ForMember(t => t.People, opt => opt.MapFrom(t => t.Items));
cfg.CreateMap<IDictionary<string, PersonFrom>, IDictionary<string, PersonTo>>()
.ConstructUsing((t, c) => t.Select(t => new PersonTo { Age = t.Value.Age, Name = t.Key }).ToDictionary(k => k.Name, v => v))
.ForMember(t => t.Keys, opt => opt.Ignore())
.ForMember(t => t.Values, opt => opt.Ignore());
});
答案 0 :(得分:-1)
您可以尝试这样
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<PersonFrom, PersonTo>().ForMember(x => x.Age, o => o.MapFrom(y => y.Age));
cfg.CreateMap<KeyValuePair<string, PersonFrom>, KeyValuePair<string, PersonTo>>()
.ConstructUsing(x => new KeyValuePair<string, PersonTo>(x.Key,new PersonTo { Age = x.Value.Age}));
cfg.CreateMap<HouseFrom, HouseTo>().ForMember(x=>x.People,o=>o.MapFrom(y=>y.Items));
});
IMapper mapper = config.CreateMapper();
var testDict = new Dictionary<string, PersonFrom>();
var testValue = new PersonFrom()
{
Age = 100
};
var testValue2 = new PersonFrom()
{
Age = 200
};
testDict.Add("key1", testValue);
testDict.Add("key2", testValue2);
var houseFrom = new HouseFrom { Items = testDict };
var houseTo = mapper.Map<HouseFrom,HouseTo>(houseFrom);
foreach (var item in houseTo.People)
{
Console.WriteLine(item.Key+" "+item.Value.Name +" "+item.Value.Age);
}