我有一个viewmodel需要以分号分隔的文本框显示某个IEnumerable
字段。起初我想过使用DefaultModelBinder
来转换它,但我无法思考如何在两个方向上实现它(dto< - > viewmodel)。
Nicknames是我试图显示为由分号分隔的一个文本框的字段。
public class Parent
{
public IEnumerable<Child> Children { get; set; }
}
public class Child
{
public IEnumerable<string> Nicknames { get; set; }
}
所以我决定尝试使用AutoMapper,我创建了两个ViewModel:
public class ParentViewModel
{
public IEnumerable<ChildViewModel> Children { get; set; }
}
public class ChildViewModel
{
public string Nicknames { get; set; }
}
然后,我为孩子们创建了这样的映射(为了简洁省略了其他方式的转换)
Mapper.CreateMap<Child, ChildViewModel>().ForMember(
d => d.Nicknames, o => o.ResolveUsing<ListToStringConverter>().FromMember(s => s.Nicknames);
然后,对于父母,创建了一个天真的地图(再次,省略了另一种方式)
Mapper.CreateMap<Parent, ParentViewModel>();
我真的期望子映射会自动发生,但它们没有,我已经创建了太多“正确”的代码来解决一个非常简单的问题,在任何其他更简单/更老的非MVC环境中,我都会很久以前完成:)我怎么能继续告诉AutoMapper转换孩子而不用另外写“儿童成员解析器”。
我是否已经推翻了这个并且有一种更简单的方法?
谢谢!
答案 0 :(得分:12)
试
Mapper.CreateMap<Parent, ParentViewModel>();
Mapper.CreateMap<Child, ChildViewModel>();
var v = Mapper.Map<Parent, ParentViewModel>(parent);
答案 1 :(得分:4)
找到适用于我的解决方案https://stackoverflow.com/a/7555977/1586498:
Mapper.CreateMap<ParentDto, Parent>()
.ForMember(m => m.Children, o => o.Ignore()) // To avoid automapping attempt
.AfterMap((p,o) => { o.Children = ToISet<ChildDto, Child>(p.Children); });
ToISet
函数在上面的链接中定义。
简单的例子'只需在LinqPad中工作' - 因此需要进行更多的调查。
工作计划的完整清单:
public class Child{ public string Name {get; set; }}
public class ChildDto{ public string NickName {get; set; }}
public class Parent{ public virtual IEnumerable<Child> Children {get; set; }}
public class ParentDto{ public IEnumerable<ChildDto> Kids {get; set; }}
private static void Main()
{
AutoMapper.Mapper.CreateMap<Parent, ParentDto>().ForMember(d=>d.Kids, opt=>opt.MapFrom(src=>src.Children));
AutoMapper.Mapper.CreateMap<Child, ChildDto>().ForMember(d=>d.NickName, opt=>opt.MapFrom(src=>src.Name));
var pList = new HashSet<Parent>{
new Parent{ Children = new HashSet<Child>{new Child{Name="1"}, new Child{Name="2"}}},
new Parent{ Children = new HashSet<Child>{new Child{Name="3"}, new Child{Name="4"}}},
};
var parentVm = AutoMapper.Mapper.Map<IEnumerable<Parent>, IEnumerable<ParentDto>>(pList);
parentVm.Dump();
}