我有两个Model类Author和Book以及两个DTO类BookDTO和BookDetailDTO,如下所示
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进行映射,如下所示
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();
}
}
现在我通过BooksController获取书籍列表
1 -> IEnumerable
列出书籍清单。
但是当我在MapConfig.cs中取消注释BookDetailDTO的映射时,我试图获取Books列表,它会抛出以下错误
映射类型:IEnumerable
1[[BookService.Models.Book, BookService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> System.Collections.Generic.IEnumerable
1 System.Collections.Generic.IEnumerable"dataList":[ { "id":1, "code":"TN", "name":"TestName", "city":{ "cityCode":"ABC", "cityName":"ABC City" },"country":{ "countryCode":"NG", "countryName":"Nigeria" }, "isOnline":true } ]
1 [[BookService.Models.BookDTO, BookService,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]
我需要从Book到BookDetailDTO的映射来显示书的详细信息。 我究竟做错了什么?我使用AutoMapper 5.1.1
答案 0 :(得分: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查询。性能更好
ProjectTo支持返回IQuerable对象。
public IQueryable<BookDTO> GetBooks()
{
return db.Books.ProjectTo<BookDTO>();
}
了解更多信息
https://github.com/AutoMapper/AutoMapper/wiki/Queryable-Extensions
答案 1 :(得分:0)
在MapConfig类中,您定义了两次地图,Book - &gt; BookDTO,然后Book - &gt; BookDetailDTO。第二个地图定义覆盖了第一个定义,当你调用Mapper.Map,IEnumerable&gt;(db.Books)时,automapper会投诉,因为automapper不知道如何映射Book - &gt; BookDTO。这就是你收到错误信息的原因。
要解决此问题,您可以定义Book - &gt; BookDTO或Book - &gt; BookDetailDTO,而不是两者。
答案 2 :(得分: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));
});
虽然这解决了我的问题,但我不确定这是最好的方法。如果任何团体对如何映射项目中的所有映射有更好的答案,请分享相同的内容。