2016-09-27 22 views
2

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; } 
} 

以下のように私は今、私はのリストを取得し、私は

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()); 

    } 
} 

以下のようにマッピングを行うためにAutoMapperを使用する2つのモデルクラスの著者とブックと2つのDTOクラスBookDTOとBookDetailDTOを持っていますBooksControlを通じて

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(); 
    } 
} 

書籍のリストを記載しています。

しかし、私はMapConfig.csでBookDetailDTOのマッピングをアンコメントし、私は本のリストを取得しようとすると、それは次のようなエラーに

マッピングタイプスロー:IEnumerableをに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、カルチャニュートラル、PublicKeyToken = = null]]

私は詳細を表示するブックからBookDetailDTOへのマッピングを必要とします本の 私は何が間違っていますか?私はAutoMapper 5.1.1を使用しています

答えて

0

、私たちは、これが私の問題を修正していてもinitializeメソッド

 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の前に一度initializeを呼び出す必要があります(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クエリを編集します。これは、パフォーマンスのためのより良いです

IQuerableオブジェクトにを返すこの enter image description here

ProjectToのサポートをインストールします。 MapConfigクラスで

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

私はあなたが追加する方法を追加しました;)@SimplyStupid –

0

、あなたは二度マップを定義し、ブック - > BookDTO、そしてブック - > BookDetailDTO。 automapperがBook - > BookDTOのマッピング方法を知らなかったので、2番目のマップ定義が最初の定義をオーバーライドし、Mapper.Map、IEnumerable>(db.Books)を呼び出すと、automapperは問題になります。それがエラーメッセージを出した理由です。

問題を解決するには、Book - > BookDTOまたはBook - > BookDetailDTOのいずれかを定義するか、両方を定義しないでください。この1つは私の問題を修正

+0

私はBook-> BookDTOまたはBook-> BookDetailDTOのいずれかでテストしましたが、期待どおりに動作しました。 @SimplyStudpidそれを試してからこれを答えにしてください。何か問題がある場合はお尋ねください。ありがとう。 –

+0

私は私の質問でBook-> BookDTOが動作すると言いましたが、BookDetailDTOにマップする必要があります。要件はこのようなもので、書籍のリストを表示します。本を選択すると、その本の詳細が表示されます。どちらも同じモデルを指します。 – MemoryLeak