使用AutoMapper映射问题?

时间:2016-09-27 08:36:54

标签: c# automapper

我有两个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

3 个答案:

答案 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查询。性能更好

安装此 enter image description here

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

虽然这解决了我的问题,但我不确定这是最好的方法。如果任何团体对如何映射项目中的所有映射有更好的答案,请分享相同的内容。