首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在DTO中映射相关DTO列表:嵌套DTO映射

如何在DTO中映射相关DTO列表:嵌套DTO映射
EN

Stack Overflow用户
提问于 2019-07-18 22:11:31
回答 3查看 3.8K关注 0票数 0

假设您在一个大型数据库中有一个完整定义的图书和作者关系,以及许多其他关系

代码语言:javascript
复制
public class Book
{
   public int Id { get; set; }
   public string Title { get; set; }
   ...
   Public int AuthorId { get; set; }
   Public Author Author { get; set; }
}

public class Author
{
   public int Id { get; set; }
   public int GroupId { get; set; }
   public string Name { get; set; }
   ...
   public List<Book> Books { get; set; }
   ...
}

在您的控制器中,您希望返回一个作者列表,每个作者都包含使用DTO与他们相关联的图书列表。

代码语言:javascript
复制
public class BookDTO
{
   public int Id { get; set; }
   public string Title { get; set; }
}

public class AuthorDTO
{
   public int Id { get; set; }
   public string Name { get; set; }
   public List<BookDTO> Books { get; set; }
}

在DTO中生成DTO列表的正确方法是什么?

你能做这样的事情吗?

代码语言:javascript
复制
var author = from a in _context.authors.Where(a => a.groupId == someGroup)
   select new AuthorDTO()
   {
      Id = a.Id,
      Name = a.Name,
      Books = (from b in a.Books
         select new BookDTO()
         {
            Id = b.Id,
            Title = b.Title
         }).ToList()
   };

或者像这样的东西?

代码语言:javascript
复制
var author = from a in _context.authors.Where(a => a.groupId == someGroup)
   select new AuthorDTO()
   {
      Id = a.Id,
      Name = a.Name,
      Books = (from b in _context.books.Where(b => b.AuthorId == a.AuthorId)
         select new BookDTO()
         {
            Id = b.Id,
            Title = b.Title
         }).ToList()
    };

编辑:

希望说得更清楚一点,我在这里重新措辞并重新提出了我的问题:

How to return list of DTO with nested lists of related DTO

EN

回答 3

Stack Overflow用户

发布于 2019-07-18 22:42:51

您可以使用AutoMapper来完成此操作。你不需要在任何地方重复你自己。您需要添加Profile,以便每次调用IMapper.Map函数时映射都能正常工作。

请参阅此示例

代码语言:javascript
复制
  public class BookDTO
  {
     public int Id { get; set; }
     public string Title { get; set; }

     public class MapProfile:AutoMapper.Profile{
          public MapProfile(){
              CreateMap<Book,BookDTO>().ReverseMap();
          }
     }
  }

  public class AuthorDTO
  {
     public int Id { get; set; }
     public string Name { get; set; }
     public List<BookDTO> Books { get; set; }


     public class MapProfile:AutoMapper.Profile{
          public MapProfile(){
              CreateMap<Author,AuthorDTO>()
              .ForMember(dest.Id, opt => opt.MapFrom(src.Id))
              .ForMember(dest.Name, opt => opt.MapFrom(src.Name))
              .ForMember(dest.Books, opt => opt.MapFrom(src.Books));
          }
     }
  }

现在,在您的控制器中,您需要注入IMapper才能使用IMapper.Map<TSource, TDestination>方法。

代码语言:javascript
复制
     public class AuthorController : Controller{

         private readonly IMapper mapper;
         private readonly Context context;

           public AuthorController(IMapper mapper, Context context){
                 mapper =mapper;
                //...context=context;
           }
           public IActionResult Index(){
              var authors = context.Author.Include(a=>a.Book).ToList();
             var authorDTOs = mapper.Map<List<AuthorDTO>>(authors);
             return View(authorDTOs);
           }
     }
票数 1
EN

Stack Overflow用户

发布于 2019-07-18 23:09:15

这是Mapper配置文件示例。Profile类来自于Automapper lib。

代码语言:javascript
复制
public class ApplicationServiceAutoMapperProfile : Profile
{
    public ApplicationServiceAutoMapperProfile()
    {
         //Don't use ForMember method if you want to show Id's
         CreateMap<Book, BookDTO>()
            .ForMember(m => m.Id, opt => opt.Ignore());

         CreateMap<Author, AuthorDTO>()
            .ForMember(m => m.Id, opt => opt.Ignore());
    }
}

这就是map.GetAuthors方法返回映射Dtos的方式。

代码语言:javascript
复制
public class CustomService {
    private readonly IMapper _mapper;
    private readonly DBContext _context;

    public CustomService(IMapper mapper, DBContext context){
        _mapper = mapper;
        _context = context;
    }

    public IEnumerable<AuthorDTO> GetAuthors(){
        //Automapper automaticaly maps authors's bookdto's also.
        var authors = _context.authors.Where(a => a.groupId == 2).ToList();
        return _mapper.Map<List<AuthorDTO>>(authors);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2019-07-18 22:27:32

我的意思是你可以这样做:

代码语言:javascript
复制
var q = from b in Books
        group b by b.Author into g
        select new AuthorDTO 
        { 
           Name = g.Key.Name, 
           Books = g.Select(gi => new BookDTO { Title = gi.Title })
        };

为此,不要将Books声明为List<BookDTO>,而是将其声明为IEnumerable<BookDTO>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57096554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档