2013-01-08 50 views
3

我遇到了Automapper問題。我建立了一個測試窗體表單應用程序,下面是代碼。也看看每個MessageBox後的意見:Automapper用子對象覆蓋丟失的源屬性列表

public class FirstClass 
    { 
     public string FirstProp { get; set; } 
     public IList<FirstClassChild> Children { get; set; } 
    } 

    public class FirstClassChild 
    { 
     public string FirstChildProp { get; set; } 
    } 

    public class SecondClass 
    { 
     public string FirstProp { get; set; } 
     public string SecondProp { get; set; } 
     public IList<SecondClassChild> Children { get; set; } 
    } 

    public class SecondClassChild 
    { 
     public string FirstChildProp { get; set; } 
     public string SecondChildProp { get; set; } 
    } 

    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 

      AutoMapper.Mapper.CreateMap<FirstClass, SecondClass>(); 
      AutoMapper.Mapper.CreateMap<FirstClassChild, SecondClassChild>(); 

      var f = new FirstClass { FirstProp = "FirstClass" }; 
      f.Children = new List<FirstClassChild> { new FirstClassChild { FirstChildProp = "FirstClass" } }; 
      var s = new SecondClass { FirstProp = "SecondClass", SecondProp = "SecondClass" }; 
      s.Children = new List<SecondClassChild> { new SecondClassChild { FirstChildProp = "SecondClass", SecondChildProp = "SecondClass" } }; 
      AutoMapper.Mapper.Map(f, s); 

      var fc = new FirstClassChild { FirstChildProp = "FirstClass" }; 
      var sc = new SecondClassChild { FirstChildProp = "SecondClass", SecondChildProp = "SecondClass" }; 
      AutoMapper.Mapper.Map(fc, sc); 

      MessageBox.Show(sc.FirstChildProp);//FirstClass as expected 
      MessageBox.Show(sc.SecondChildProp);//SecondClass as expected 

      MessageBox.Show(s.FirstProp);//FirstClass as expected 
      MessageBox.Show(s.SecondProp);//SecondClass as expected 
      MessageBox.Show(s.Children.First().FirstChildProp);//FirstClass as expected 
      MessageBox.Show(s.Children.First().SecondChildProp);//Empty not expected!! 

     } 
    } 

我該怎麼做才能避免這種情況?預期這種行爲? 無論如何,任何人都可以指導我如何使SecondClass孩子SecondChildProp保持「SecondClass」,因爲它是在映射發生之前。

回答

5

我問了一個類似的問題here,發現另一個類似的問題here

我認爲@PatrickSteele提出了一個很好的觀點:AutoMapper應該如何將源列表映射到現有對象的目標列表,當dest列表可能不一定與源列表有任何相似之處?即「But what if one list has 3 and the other list has 5?

如果你確信FirstClassSecondClass有相同數量的Children如果FirstClass的第n個子總是對應於SecondClass的第N個孩子,你可以嘗試這樣的事情:

Mapper.CreateMap<FirstClass, SecondClass>() 
    .ForMember(m => m.Children, o => o.Ignore()) 
    .AfterMap((src, dest) => 
     { 
      for (var i = 0; i < dest.Children.Count; i++) 
       Mapper.Map(src.Children[i], dest.Children[i]); 
     }); 

,或者如果FirstChildProp是某種獨特的鍵:

Mapper.CreateMap<FirstClass, SecondClass>() 
    .ForMember(m => m.Children, o => o.Ignore()) 
    .AfterMap((src, dest) => 
     { 
      foreach (var dChild in dest.Children) 
      { 
       var sChild = src.Children.Single(c => c.FirstChildProp == dChild.FirstChildProp); 
       Mapper.Map(sChild, dChild); 
      } 
     }); 
+0

這很有道理,謝謝。我不承認複雜性,被我孤立的案件蒙上了一層陰影。 – John

+0

第二個想法,關於AutoMapper無法知道列表中的子項的論證等等。AutoMapper映射FirstChildProp是否有點尷尬?似乎與我不一致。 – John

+1

@John - 在幕後,我不認爲Automapper將FirstChildProp **映射到**現有的SecondClassChild對象中。相反,我期望它完全** **了SecondClass的'Children'列表,並用它剛剛創建的新的SecondClassChild列表覆蓋它(使用'FirstClass.Children'作爲映射源)。這應該變得更加明顯當source.Children和dest.Children列表具有不同的長度時。 – Merenzo