2011-12-11 49 views
2

我有一個奇怪的案例,我對AutoMapper很新,我不明白髮生了什麼。AutoMapper - 如何選擇不執行「內部」地圖?

我有兩個類

public class Person 
{ 
    public List<Friend> Friends {get;set;} 
} 

public class PersonView : Person 
{ 
    public new List<FriendView> Friends {get;set;} 
} 

和地圖

Mapper.CreateMap<Person, PersonView>().ForMember(d => d.Friends, 
    o => o.ResolveUsing<FriendViewResolver>().FromMember(s => s.Friends)); 

,但是,我也有這個地圖,它有自己的映射:

Mapper.CreateMap<Friend, FriendView>().ForMember(/* a lot of stuff */); 

現在,裏面FriendViewResolver - 我爲每個朋友打電話Mapper.Map<Friend, FriendView>()。但由於某些原因,在運行之後,一些屬性會丟失,並且從代碼中跳過,似乎AutoMapper會在列表中進行第二次傳遞。

我想讓FriendViewResolver在列表上運行,因爲它正在對Friends的整個集合進行遞歸調整,但我不明白爲什麼AM會在成員有解析器規則的情況下進行第二次傳遞。

我真的很希望它有道理。

編輯:問題發生在我運行Mapper.Map<Person, PersonView>();時,我看到它運行FriendViewResolver並且結果正確,但調試器中的下一步再次運行映射並混淆已映射的對象。

回答

0

我想你可以用這個度日:

Mapper.CreateMap<Person, PersonView>(); 
Mapper.CreateMap<Friend, FriendView>().ForMember(/* a lot of stuff */); 

<Person, PersonView>地圖會自動試圖映射友性能,因爲它們具有相同的名稱。 <Friend, FriendView>地圖應該照顧實際屬性映射。

+0

不,我提到爲什麼我需要'FriendViewResolver' - 它需要在整個列表上運行,我不能做1對1映射 – Madd0g

+0

如果是這樣的話,你需要''映射聲明?如果你刪除它(暫時的,用於測試),那麼''映射是否按預期工作? – hawkke

+0

我需要創建該映射,我在'FriendViewResolver'中手動調用它。沒有它'FriendViewResolver'不能保留結果(因爲輸入類型不同),所以有一個不同的問題 – Madd0g

4

PersonView派生自Person。這不是AutoMapper應該如何使用的。它應該用於映射不同的類。看起來你在這裏試圖做的是你有一個域模型Person,並且你正試圖創建一個視圖模型PersonView,它將在視圖中使用。這很好,正是你應該做的,除了視圖模型不應該從域模型派生。它是獨立的。然後你使用AutoMapper在它們之間進行映射。

所以你PersonView類應該是這樣的:

public class PersonView 
{ 
    public List<FriendView> Friends {get;set;} 
} 

,現在你將有2個映射定義:

Mapper.CreateMap<Friend, FriendView>(); 
Mapper.CreateMap<Person, PersonView>(); 

,當你有你的域模型的實例(人)你將能夠映射到視圖模型(PersonView)。

+0

這個方法實際上工作得很好,我已經在派生類中使用它了。我要麼轉換要麼添加數據,爲什麼浪費時間在視圖模型中再次指定成員,如果我可以繼承? 但我的問題是 - 我不希望列表成員被AM轉換 - 我想用我自己的解析器自己做。 – Madd0g

+3

爲什麼要繼承? AutoMapper和獨立視圖模型的好處之一是視圖模型是爲視圖設計的。繼承重新實現了持久性模型和視圖之間的鏈接。 –

+0

@JimmyBogard,你認爲繼承是我試圖做的問題嗎?在我看來,AM不應該嘗試映射列表成員中的實體,前提是它具有解析器 – Madd0g