2014-01-23 65 views
1

考慮以下情形集合中的類型:Automapper:忽略尚未建立

public class DestinationType1 { } 

    public class DestinationType2 { } 

    public class SourceType { } 

    public class SourceTypeA : SourceType { } 

    public class SourceTypeB : SourceType { } 

我設置了這些映射:

 Mapper.CreateMap<SourceType, DestinationType2>(); 

     Mapper.CreateMap<SourceTypeB, DestinationType2>(); 

     Mapper.CreateMap<SourceType, DestinationType1>(); 

     Mapper.CreateMap<SourceTypeA, DestinationType1>(); 

然後嘗試映射以下:

 var sourceTypes = new List<SourceType>{new SourceTypeA(), new SourceTypeB()}; 
     var destinationType1s = Mapper.Map<List<DestinationType2>>(sourceTypes); 
     var destinationType2s = Mapper.Map<List<DestinationType1>>(sourceTypes); 

我想達到的目的是爲了destinationType1s只有一個成員,從源列表SourceTypeA映射,一個nd destinationType2s只有一個從SourceTypeB映射的映射。但是,我得到的是兩個來源類型映射的列表中的兩個元素。

這是可以實現的某種程度上開箱即用,還是我需要寫我自己的價值解析器或類似?

回答

1

您可以使用OfType LINQ擴展方法來過濾sourceTypes列表。

var sourceTypes = new List<SourceType>{new SourceTypeA(), new SourceTypeB()}; 
var destinationType1s = Mapper.Map<List<DestinationType1>>(sourceTypes.OfType<SourceTypeA>()); 
var destinationType2s = Mapper.Map<List<DestinationType2>>(sourceTypes.OfType<SourceTypeB>()); 

OfType<type>將產生IEnumerable<type>所以你也可以刪除2個地圖的基礎SourceType如果你不打算使用它們。

如果您想篩選多個類型,那麼您可以創建類似於OfType的自己的擴展方法,該方法需要一個類型列表或者使用DestinationType並查找映射到它的類型。下面是一些作品使用Mapper.FindTypeMapFor僅過濾兼容類型:

//Mapper.CreateMap<SourceType, DestinationType2>(); -- don't want this! 

Mapper.CreateMap<SourceTypeB, DestinationType2>(); 

//Mapper.CreateMap<SourceType, DestinationType1>(); -- don't want this! 

Mapper.CreateMap<SourceTypeA, DestinationType1>(); 

var sourceTypes = new List<SourceType> { new SourceTypeA(), new SourceTypeB() }; 
var destinationType1s = Mapper.Map<List<DestinationType1>>(sourceTypes.CompatibleMappedTypes<DestinationType1>()); 
var destinationType2s = Mapper.Map<List<DestinationType2>>(sourceTypes.CompatibleMappedTypes<DestinationType2>()); 

...

static class Extensions 
{ 
    public static IEnumerable CompatibleMappedTypes<TDestination>(this IEnumerable source) 
    { 
     foreach (var s in source) 
     { 
      if (Mapper.FindTypeMapFor(s.GetType(), typeof(TDestination)) != null) yield return s; 
     } 
    } 
} 
+0

這肯定是一個解決方案,但是「真正」的情況下,我有涉及更多的源和目標對象,所以我想要說一個列表有A,B和C類型映射到它,另一個D,E和F,那麼我將不得不創建另一個基類,A,B和C從D繼承, E,F我想。如果你能指定automapper應該跳過任何沒有顯式映射的類,那將是很好的。 –

+0

好吧,你已經給它一個基類的映射,所以它確實有一個明確的映射列表中的所有內容。 – CoderDennis

+0

你是正確的,我明白爲什麼我會在映射列表中獲得這兩個元素,而你的解決方案可能是我必須要做的。但是,如果有一種方法可以告訴automapper只映射爲該特定類設置映射的派生類型,那將會非常有用。 –