2014-04-05 99 views
4

我試圖將IEnumerable映射到List。我不知道如何讓它工作。這是我到目前爲止所嘗試過的。如何使用AutoMapper將IEnumerable映射到列表

我收到一個錯誤「成員的自定義配置只支持一個類型的頂級單個成員。」

Source: IEnumerable<Source> 
Target: List<Target> 

AutoMapper.Mapper.Map(sourceIEnum, TargetList); 

Mapper.CreateMap<IEnumerable<Source>, List<Target>>() 
    .ForMember(f => f, mp => mp.MapFrom(
            mfrom => mfrom.Select(s => AutoMapper.Mapper.Map(s, new Target()) 
           ).ToList()) 
      ); 

Mapper.CreateMap<Source, Target>() 
    .ForMember(f => f.TargetPropertyA, mp => mp.MapFrom(mfrom => mfrom.FromA.Value)) 
    .ForMember(f => f.TargetPropertyB, mp => mp.MapFrom(mfrom => mfrom.FromB.Value)) 
    .ForMember(f => f.TargetPropertyC, mp => mp.MapFrom(mfrom => mfrom.FromC.Value)) 
    .ForMember(f => f.InnerObjectTarget, mp => mp.MapFrom(
            mfrom => mfrom.Select(s => AutoMapper.Mapper.Map(s, new InnerObjectTarget()) 
           ).ToList()) 
      );  

Mapper.CreateMap<SourceInner, TargetInner>() 
     .ForMember(f => f.TargetInnerPropA, m => m.MapFrom(source => source.InnerA)) 
     .ForMember(f => f.TargetInnerPropB, m => m.MapFrom(source => source.InnerB)) 
     .ForMember(f => f.TargetInnerPropC, m => m.MapFrom(source => source.InnerC)); 

回答

2

只要來源目標映射定義,你並不需要明確定義IEnumerable<Source>List<Target>映射。

Automapper足夠智能,可以自動映射基本集合(List,IEnumerable,Collection等)如果集合元素類型被映射。所以刪除集合映射之間的所有代碼並重試。

這段代碼..

Mapper.CreateMap<IEnumerable<Source>, List<Target>>() 
    .ForMember(f => f, mp => mp.MapFrom(
            mfrom => mfrom.Select(s => AutoMapper.Mapper.Map(s, new Target()) 
           ).ToList()) 
      ); 
5

有多種方法可以在IEnumerable<Source>映射到一個IEnumerable<Target>。我會展示三個最方便的。

服用AdventureWorks database(2008R2)作爲一個例子,我定義了三個DTO類:

class ProductModelDto 
{ 
    public string Name { get; set; } 
    public IEnumerable<ProductDto> Products { get; set; } 
} 

class ProductDto 
{ 
    public string Name { get; set; } 
    public string Number { get; set; } 
    public IEnumerable<ProductReviewDto> ProductReviews { get; set; } 
} 

class ProductReviewDto 
{ 
    public string ReviewerName { get; set; } 
    public string Email { get; set; } 
} 

這是我所定義的唯一的映射:

Mapper.CreateMap<ProductModel, ProductModelDto>(); 
Mapper.CreateMap<Product, ProductDto>() 
     .ForMember(dto => dto.Number, m => m.MapFrom(p => p.ProductNumber)); 
Mapper.CreateMap<ProductReview, ProductReviewDto>() 
     .ForMember(dto => dto.Email, m => m.MapFrom(pr => pr.EmailAddress)); 

僅有的查詢:

// A ProductModel having a Product with ProductReviews 
var query = db.ProductModels.Where(pm => pm.ProductModelID == 64); 

現在最方便的方法,在我看來,映射源ProductModel s到IEnumerable<ProductModelDto>有三個:

1. query.Select(Mapper.Map<ProductModelDto>) 
2. Mapper.Map<List<ProductModelDto>>(query) 
3. query.ProjectTo<ProductModelDto>() (Project().To<> prior to v. 4.1.0) 

如果你這樣做ToList(),你已經映射到IEnumerableList

輸出是三個方案中是相同:

- HL Mountain Pedal 
    - HL Mountain Pedal; PD-M562 
    - David; [email protected] 
    - Jill; [email protected] 

正如你看到的,AutoMapper不需要爲IEnumerable小號明確的映射定義。不適用於頂層而不適用於嵌套集合。當源和目標類中的名稱相同時,它還映射一個嵌套集合,併爲該集合中的元素定義映射。

案例是一個特例。它將IQueryable投射到目標,該目標仍然是IQueryable。在之後應用的謂詞映射仍被轉換爲SQL,並且該查詢嘗試僅選擇數據庫中投影所需的字段。當DTO嵌套時,後者並不總是成功,就像在這種情況下一樣。 Linq-to SQL似乎用選項3執行了兩個查詢(但對於1和2來說是三個)。

+0

列表中的數字1似乎不起作用,您錯過了該語法中的某些內容嗎?我正在返回IEnumerable ...(來源) – Choco

+0

@Choco。請更具體一些。 –

+0

query.Select(Mapper.Map )我只問你是否錯過了一些軟支架或其他東西,這些都是......重複檢查。正如我試圖獲得IEnumerable列表(源)轉換。 – Choco

相關問題