2016-09-27 311 views
2

我有兩個模型類作者和書兩DTO類BookDTO和BookDetailDTO如下圖所示AutoMapper映射問題?

public class Author 
{ 
    public int Id { get; set; } 
    [Required()] 
    public string Name { get; set; } 
} 

public class Book 
{ 
    public int Id { get; set; } 
    [Required()] 
    public string Title { get; set; } 
    public int Year { get; set; } 
    public decimal Price { get; set; } 
    public string Genre { get; set; } 
    public int AuthorId { get; set; } 
    public virtual Author Author { get; set; }   
} 

public class BookDTO 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string AuthorName { get; set; } 
} 

public class BookDetailDTO 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public int Year { get; set; } 
    public decimal Price { get; set; } 
    public string AuthorName { get; set; } 
    public string Genre { get; set; } 
} 

我使用AutoMapper做映射如下圖所示

public class MapConfig 
{ 
    public static void RegisterMapping() 
    { 
     AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Book, BookDTO>() 
      .ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.Author.Name))); 
     AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Book, BookDTO>() 
      .ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.Author.Name)).ReverseMap()); 


     //AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Book, BookDetailDTO>() 
      //.ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.Author.Name))); 
     //AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Book, BookDetailDTO>() 
      //.ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.Author.Name)).ReverseMap()); 

    } 
} 

現在,我得到的名單BooksController

public class BooksController : ApiController 
{ 
    private BookServiceContext db = new BookServiceContext(); 


    public IQueryable<BookDTO> GetBooks() 
    { 

     var books = AutoMapper.Mapper.Map<IEnumerable<Book>, IEnumerable<BookDTO>>(db.Books); 
     return books.AsQueryable(); 
    } 
} 

它列出書籍列表。

但是,當我取消註釋映射BookDetailDTO在MapConfig.cs,我試圖讓書籍的列表,它引發以下錯誤

映射類型:IEnumerable的1 -> IEnumerable 1 System.Collections中 .Generic.IEnumerable 1[[BookService.Models.Book, BookService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> System.Collections.Generic.IEnumerable 1 [[BookService.Models.BookDTO, bookService的,版本= 1.0.0.0,文化=中性公鑰=空]]

我需要從預訂至BookDetailDTO映射以顯示詳細信息這本書。 我在做什麼錯?我使用AutoMapper 5.1.1

回答

0

這一個固定我的問題,我認爲,我們必須把所有的映射初始化方法

 AutoMapper.Mapper.Initialize(cfg => 
     { 
      cfg.CreateMap<Book, BookDTO>() 
       .ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.Author.Name)); 
      cfg.CreateMap<Book, BookDetailDTO>() 
      .ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.Author.Name)); 
     }); 

即使這個固定我的問題,我不知道這是做的最好的辦法裏面。如果任何機構對如何映射項目中的所有映射有更好的答案,請分享一致。

+1

這是正確的路要走。您需要在AppDomain之前調用一次初始化(就像初始化您的ORM一次或DI容器等一樣)。大多數人做的是通過配置文件初始化AutoMapper: https://github.com/AutoMapper/AutoMapper/wiki/Configuration#assembly-scanning-for-auto-configuration –

0

1-)您完成配置。我去掉不必要的部分:

public class MapConfig 
{ 
    public static void RegisterMapping() 
    { 
     AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Book, BookDTO>() 
      .ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.Author.Name)).ReverseMap()); 


     AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Book, BookDetailDTO>() 
      .ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.Author.Name)).ReverseMap()); 

    } 
} 

2-)不使用Mapper.Map方法,因爲Mapper.Map執行查詢。相反,使用ProjectTo。它不執行查詢。它編輯你的ef查詢。它是性能更好的

安裝此 enter image description here

ProjectTo支持返回IQuerable對象

public IQueryable<BookDTO> GetBooks() 
{ 
    return db.Books.ProjectTo<BookDTO>(); 
} 

欲瞭解更多信息

https://github.com/AutoMapper/AutoMapper/wiki/Queryable-Extensions

+1

這回答問題的方式是什麼?這應該是一個評論。 – kiziu

+0

@Sercan Timocin感謝您關注此問題,但沒有可用的ProjectTo方法。謝謝(你的)信息。 我想我正在做一些映射問題。 – MemoryLeak

+0

我添加了pic。如何添加;)@SimplyStupid –

0

在MapConfig類,你定義的地圖兩次,圖書 - > BookDTO,然後書 - > BookDetailDTO。第二個地圖定義重寫了第一個定義,當你調用Mapper.Map,IEnumerable>(db.Books)時,automapper會投訴,因爲automapper不知道如何映射Book - > BookDTO。這就是你得到這個錯誤信息的原因。

要解決該問題,您可以定義Book - > BookDTO或Book - > BookDetailDTO,而不是兩者。

+0

我已經用Book-> BookDTO或Book-> BookDetailDTO對它進行了測試,它們按預期工作。 @SimplyStudpid嘗試一下,然後將其標記爲答案。如果您有任何問題,請詢問。謝謝。 –

+0

我在我的問題中提到Book-> BookDTO的作品,但我需要將其映射到BookDetailDTO。要求是這樣的,顯示書籍列表。選擇一本書,它應該顯示書的細節。兩者都指相同的型號。 – MemoryLeak