2011-11-25 15 views
9

Tengo un modelo de vista que debe mostrar un determinado campo IEnumerable como cuadro de texto separado por punto y coma. Al principio pensé en usar DefaultModelBinder para transformarlo, pero tuve problemas para pensar cómo lograrlo en ambas direcciones (dto < -> viewmodel).AutoMapper: asignación de colecciones secundarias en el modelo de vista

Apodos es el campo que trato de mostrar como un cuadro de texto separado por punto y coma.

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

public class Child 
{ 
    public IEnumerable<string> Nicknames { get; set; } 
} 

Así que decidieron probar AutoMapper, creé dos ViewModels:

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

public class ChildViewModel 
{ 
    public string Nicknames { get; set; } 
} 

A continuación, he creado asignaciones, como esto para los niños (se omite la conversión otras vías por razones de brevedad)

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

Entonces, para el padre, creó un mapa ingenua (de nuevo, se omite la otra vía)

Mapper.CreateMap<Parent, ParentViewModel>(); 

Realmente esperaba que las asignaciones de elementos secundarios se realizaran automáticamente, pero no es así, ya he creado demasiado código "adecuado" para resolver un problema realmente simple que en cualquier otro entorno no MVC más simple/antiguo, hacerse con mucho tiempo atrás :) ¿Cómo puedo proceder y decirle a AutoMapper que transforme los niños sin escribir otra "resolución de miembros hijos"?

¿He pensado demasiado sobre esto y hay una manera más simple?

¡Gracias!

Respuesta

12

tratar

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

var v = Mapper.Map<Parent, ParentViewModel>(parent); 
+0

Sí, tengo todo eso (4 disposiciones: niño <-> childView, padre <-> parentView), pero los elementos secundarios no se convierten cuando llamo 'Mapper. Map' en el padre – Madd0g

+1

tiene los mismos nombres para las propiedades en 'ChildViewModel' y' Parent' – Rafay

+0

No, no tiene el mismo tipo de propiedades en 'Child' y' ChildViewModel' – Rafay

4

encontrado esta solución https://stackoverflow.com/a/7555977/1586498, que funciona para mí:

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); }); 

La función ToISet se define en el enlace anterior.

Ejemplos simples 'solo funcionan' en LinqPad, por lo que se necesita más investigación.

Un listado completo de un programa de trabajo:

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();  
    } 
Cuestiones relacionadas