2011-12-01 179 views
2

我在標題中提到的映射有一些問題。下面是詳細信息:Automapper映射IList <>到Iesi.Collections.Generic.ISet <>

class MyDomain 
{ 
    public Iesi.Collections.Generic.ISet<SomeType> MySomeTypes{ get; set; } 
    .... 
} 


class MyDTO 
{ 
    public IList<SomeTypeDTO> MySomeTypes{ get; set; } 
    ... 
} 

映射:

Mapper.CreateMap<MyDomain, MyDTO>().ForMember(dto=>dto.MySomeTypes, opt.ResolveUsing<DomaintoDTOMySomeTypesResolver>()); 

Mapper.CreateMap<MyDTO, MyDomain>().ForMember(domain=>domain.MySomeTypes, opt.ResolveUsing<DTOtoDomainMySomeTypesResolver>()); 

解析器:從域名

class DomaintoDTOMySomeTypesResolver: ValueResolver<MyDomain, IList<SomeTypeDTO>> 
{ 
    protected override IList<SomeTypeDTO> ResolveCore(MyDomain source) 
    { 
     IList<SomeTypeDTO> abc = new List<DemandClassConfigurationDTO>(); 
     //Do custom mapping 
     return abc; 
    } 
} 

class DTOtoDomainMySomeTypesResolver: ValueResolver<MyDTO, Iesi.Collections.Generic.ISet<SomeType>> 
{ 
    protected override Iesi.Collections.Generic.ISet<SomeType> ResolveCore(SystemParameterDTO source) 
    { 
    Iesi.Collections.Generic.ISet<SomeType> abc = new HashedSet<SomeType>(); 
    //Do custom mapping 
    return abc; 
    } 
} 

映射到DTO工程確定和預期我得到一個MyDTO對象用的IList 「SomeTypeDTO」對象。 然而,DTO映射到域引發以下錯誤:

Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. 
    ----> AutoMapper.AutoMapperMappingException : Trying to map Iesi.Collections.Generic.HashedSet`1[SomeType, MyAssembly...] to Iesi.Collections.Generic.ISet`1[SomeType, MyAssembly...] 

Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. 
    ----> System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.List`1[SomeType]' to type 'Iesi.Collections.Generic.ISet`1[SomeType] 

什麼可能我是做錯了什麼和做什麼的錯誤信息意味着什麼?似乎automapper在映射ISet(連同其具體實現HashedSet)時遇到了一些問題。我的理解是,在上述場景中,automapper應該只使用由「DTOtoDomainMySomeTypesResolver」返回的ISet引用。我也不明白爲什麼我得到「從列表轉換爲ISet錯誤」。

回答

1

這是因爲AutoMapper目前不支持ISet<>集合屬性。它在ISet<>的目標屬性已經實例化(非空)時起作用,因爲ISet<>實際上是從ICollection<>繼承的,因此Automapper可以理解並且將正確地執行集合映射。

當destination屬性爲null並且是接口類型時,它不起作用。你會得到這個錯誤,因爲automapper實際上發現它可以從ICollection<>中分配,所以它使用通用List<>實例化屬性,當automapper必須創建新的集合屬性時它是默認集合,但是當它試圖實際分配它時,它會失敗,因爲很明顯List<>不能轉換到ISet<>

有三種解決這個:

  1. 創建一個功能請求,支持ISet<>集合,並希望他們將它添加
  2. 確保屬性不爲null 。例如。在構造函數中將其實例化爲空HashSet<>。這可能會導致ORM層出現一些問題,但是可行
  3. 我最好的解決方案是創建自定義值解析器,您已經擁有該解析器,並且在屬性爲null的情況下自己實例化屬性。您需要實施IValueResolver,因爲提供的基地ValueResolver不會讓您實例化該屬性。這裏是代碼片段,我用:
​​

然後在你的映射使用opt => opt.ResolveUsing(new EntitCollectionMerge<Entity,Dto>()).FromMember(x => x.ISetMember)或者如果你有很多收集這樣的,你可以自動通過typeMaps將它們添加到所有的人。

相關問題