AutoMapper - 在viewmodel中映射子集合

Mad*_*d0g 9 c# asp.net-mvc automapper asp.net-mvc-3

我有一个viewmodel需要以IEnumerable分号分隔的文本框显示某个字段.起初我想用DefaultModelBinder它来改造它,但我很难想到如何在两个方向上实现它(dto < - > viewmodel).

昵称是我试图显示为由分号分隔的一个文本框的字段.

public class Parent
{
    public IEnumerable<Child> Children { get; set; }
}

public class Child
{
    public IEnumerable<string> Nicknames { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

所以我决定尝试AutoMapper,我创建了两个ViewModel:

public class ParentViewModel
{
    public IEnumerable<ChildViewModel> Children { get; set; }
}

public class ChildViewModel
{
    public string Nicknames { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后,我为孩子们创建了这样的映射(为了简洁省略了其他方式的转换)

Mapper.CreateMap<Child, ChildViewModel>().ForMember(
d => d.Nicknames, o => o.ResolveUsing<ListToStringConverter>().FromMember(s => s.Nicknames);
Run Code Online (Sandbox Code Playgroud)

然后,为父母创建一个天真的地图(再次,省略其他方式)

Mapper.CreateMap<Parent, ParentViewModel>();
Run Code Online (Sandbox Code Playgroud)

我真的希望子映射能够自动发生,但它们没有,我已经创建了太多"正确"的代码来解决一个非常简单的问题,在任何其他更简单/更老的非MVC环境中,我都会完成很久以前:)我怎么能继续告诉AutoMapper转换孩子而不用另外写"儿童成员解析器".

我是否已经推翻了这个并且有一种更简单的方法?

谢谢!

Raf*_*fay 12

尝试

Mapper.CreateMap<Parent, ParentViewModel>();
Mapper.CreateMap<Child, ChildViewModel>();

var v = Mapper.Map<Parent, ParentViewModel>(parent);
Run Code Online (Sandbox Code Playgroud)

  • “ChildViewModel”和“Parent”中的属性是否具有相同的名称 (2认同)

OzB*_*Bob 5

找到了这个解决方案/sf/answers/528918421/,它对我有用:

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); });
Run Code Online (Sandbox Code Playgroud)

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();    
    }
Run Code Online (Sandbox Code Playgroud)