我是Automapper的新手,我正在尝试将数据从列表中的对象映射到列表中的接口。除此之外,列表位于包含对象的不同级别:
// class definitions
public class MyViewModel
{
public int ViewModelId { get; set; }
public IList<ViewItem> Page1Selections { get; set; }
public IList<ViewItem> Page2Selections { get; set; }
}
public class ViewItem
{
public int ItemId { get; set; }
public bool IsSelected { get; set; }
}
public class MyDbModel
{
public int DbModelId { get; set; }
public IPageSelection Page1Selections { get; set; }
public IPageSelection Page2Selections { get; set; }
}
public interface IPageSelection
{
int PageNumber { get; set; }
IList<IMyDbItem> PageSelections { get; set; }
}
public class PageSelection : IPageSelection
{
public int PageNumber { get; set; }
public IList<IMyDbItem> PageSelections { get; set; }
}
public interface IMyDbItem
{
int ItemId { get; set; }
bool IsSelected { get; set; }
}
public class MyDbItem : IMyDbItem
{
public int ItemId { get; set; }
public bool IsSelected { get; set; }
}
// mapping code
MyViewModel myVm = new MyViewModel();
myVm.ViewModelId = 123;
myVm.Page1Selections = new List<ViewItem>();
myVm.Page1Selections.Add(new ViewItem() { ItemId = 1, IsSelected = true });
myVm.Page2Selections = new List<ViewItem>();
myVm.Page2Selections.Add(new ViewItem() { ItemId = 2, IsSelected = true });
Mapper.Initialize(cfg =>
{
cfg.BindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
cfg.CreateMap<MyViewModel, MyDbModel>();
cfg.CreateMap<ViewItem, IMyDbItem>();
});
MyDbModel myDb = new MyDbModel();
myDb = Mapper.Map<MyDbModel>(myVm); //<== exception here
很抱歉长篇大论。但我正在与对象接口和层次不匹配映射问题进行斗争。
答案 0 :(得分:1)
这是你可以实现这一目标的一种方式:
cfg.CreateMap<MyViewModel, MyDbModel>()
.ForMember(dest => dest.DbModelId, opt => opt.MapFrom(src => src.ViewModelId));
cfg.CreateMap<ViewItem, IMyDbItem>()
.ConstructUsing((ViewItem src) => new MyDbItem());
cfg.CreateMap<IList<ViewItem>, IPageSelection>()
.ConstructUsing((IList<ViewItem> src) => new PageSelection())
.ForMember(dest => dest.PageSelections, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.PageNumber, opt => opt.Ignore());
您收到的错误是因为IList<ViewItem>
到IPageSelection
之间没有映射。我在上面创建了这个映射。
重要的一点是ConstructUsing
电话。我在这里添加了这些,因为我假设你想使用实现你所映射的接口的具体类型。否则,AutoMapper将创建一个实现目标接口的代理类。
允许从IPageSelection.PageSelections
映射到IList<ViewItem>
的部分是opt.MapFrom(src => src)
部分。这实际上告诉AutoMapper从列表映射到内部PageSelections
属性,最终使用从ViewItem
到IMyDbItem
的映射。