问题
I have this class:
class ClassFrom
{
public int Id { get; set; }
public string Foo { get; set; }
public string Bar { get; set; }
}
I want to map it into this, with the Id
property becoming the dictionary's key:
class ClassTo
{
public string Foo { get; set; }
public string Bar { get; set; }
}
Dictionary<int, ClassTo> toDict
= mapper.Map<List<ClassFrom>, Dictionary<int, ClassTo>>(fromList);
Is there a recommended way to accomplish this?
The best way I've found to do this using Automapper has a slight code smell to me. I am essentially double-mapping the object, first to ClassTo
and then to KeyValuePair
through its constructor:
var cfg = new MapperConfiguration(c =>
{
c.CreateMap<ClassFrom, ClassTo>();
c.CreateMap<ClassFrom, KeyValuePair<int, ClassTo>>()
.ForCtorParam("key", paramOptions => paramOptions.MapFrom(from => from.Id))
.ForCtorParam("value", paramOptions => paramOptions.MapFrom(from => from));
});
IMapper mapper = new AutoMapper.Mapper(cfg);
List<ClassFrom> fromList = new List<ClassFrom>
{
new ClassFrom { Id = 1, Foo = "foo1", Bar = "Bar1" },
new ClassFrom { Id = 2, Foo = "foo2", Bar = "Bar2" }
};
Dictionary<int, ClassTo> toDict
= mapper.Map<List<ClassFrom>, Dictionary<int, ClassTo>>(fromList);
回答1:
You can just use the ToDictionary extension method in the System.Linq namespace.
//using System.Linq;
var toDict = fromList.ToDictionary
(
//Define key
element => element.Id,
//Define value
element => new ClassTo { Foo = element.Foo, Bar = element.Bar }
);
回答2:
You can use ConstructUsing instead of ForCtorParam. If you change the mapper configuration like below, it will work correctly.
var cfg = new MapperConfiguration(c =>
{
c.CreateMap<ClassFrom, ClassTo>();
c.CreateMap<ClassFrom, KeyValuePair<int, ClassTo>>()
.ConstructUsing(x => new KeyValuePair<int, ClassTo>(x.Id, new ClassTo { Bar = x.Bar, Foo = x.Foo }));
});
来源:https://stackoverflow.com/questions/51109761/mapping-a-list-to-a-dictionary