2016-09-27 257 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