2011-11-25 169 views
9

我有一個viewmodel,需要將某個IEnumerable字段顯示爲以分號分隔的文本框。起初,我想到用DefaultModelBinder來改變它,但我很難考慮如何在兩個方向上實現它(dto < - > viewmodel)。AutoMapper - 在視圖模型中映射子集合

暱稱是我試圖顯示爲以分號分隔的一個文本框的字段。

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

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

所以我決定嘗試AutoMapper,我創建了兩個的ViewModels:

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在不寫另一個「兒童成員解析器」的情況下轉換孩子。

我推翻了這個,有一個更簡單的方法嗎?

謝謝!

回答

12

嘗試

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

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

是的,我有所有的(4個映射:孩子<-> childView,父母<-> parentView),但是當我打電話'映射中的子項不轉換。在父親 – Madd0g

+1

上的地圖''你有'ChildViewModel'和'Parent'中的屬性相同的名字嗎? – Rafay

+0

不,你沒有'Child'和ChildViewModel中的相同類型的屬性 – Rafay

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