I am new with Automapper and I have a problem with mapping my classes which have many-to-many relationships. I think I need something like nested mapping but the documentation does not seem for me clearly. I know that I am doing something wrong with AutoMapper configuration but I can't figure out what's wrong.
When I am adding a new book to the database I would like to receive information about the book and the authors who are written the book. (expected JSON result is below)
I have the following classes:
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public string ISBN { get; set; }
public string Category { get; set; }
public int PublisherId { get; set; }
public Publisher Publisher { get; set; }
public ICollection<BookAuthor> BooksAuthors { get; set; }
}
public class Author
{
public int AuthorId { get; set; }
public string AuthorName { get; set; }
public string AuthorLastName { get; set; }
public ICollection<BookAuthor> BooksAuthors { get; set; }
}
public class BookAuthor
{
public int BookId { get; set; }
public Book Book { get; set; }
public int AuthorId { get; set; }
public Author Author { get; set; }
}
DTOs
public class BookForNewDto
{
public string Title { get; set; }
public string ISBN { get; set; }
public string Category { get; set; }
public int PublisherId { get; set; }
public ICollection<AuthorForNewBookDto> Authors { get; set; }
}
public class AuthorForNewBookDto
{
public int AuthorId { get; set; }
}
BookController (AddBook)
public async Task<IActionResult> AddBook([FromBody] BookForNewDto bookForNewDto)
{
var bookToCreate = _mapper.Map<Book>(bookForNewDto);
var bookToReturn = _mapper.Map<BookForNewDto>(bookToCreate);
var bookToAdd = await _context.Books.AddAsync(bookToCreate);
await _context.SaveChangesAsync();
var bookIdToAdd = bookToCreate.BookId;
var authorIdToAdd = bookForNewDto.Authors.Select(aa => aa.AuthorId).ToList();
foreach (var item in authorIdToAdd)
{
var bookAuthorToAdd = new BookAuthor()
{
BookId = bookIdToAdd,
AuthorId = item
};
var newBookAuthor = await _context.BooksAuthors.AddAsync(bookAuthorToAdd);
await _context.SaveChangesAsync();
}
return Ok(bookToReturn);
}
AutoMapper Profiler // I attached only the section which concerns Adding a new book.
public class AutoMapping : Profile
{
public AutoMapping()
{
CreateMap<BookForNewDto, Book>();
CreateMap<Book, BookForNewDto>()
.ForMember(dto => dto.PublisherId, opt => opt.MapFrom(x => x.PublisherId))
.ForMember(dto => dto.Authors, c => c.MapFrom(c => c.BooksAuthors));
CreateMap<BookForNewDto, AuthorForNewBookDto>()
.ForMember(dto => dto.AuthorId, opt => opt.MapFrom(x => x.Authors.Select(aaa => aaa.AuthorId)));
}
My question is how do I configure my AutoMapper Profiler to get the JSON result below? I have a problem with the authors. I'm still getting an empty list.
{
"title": "sample title",
"isbn": "123-41-5-12311",
"category": "test",
"publisherId": 1,
"authors": [
{
"authorId": 43
},
{
"authorId": 45
},
{
"authorId": 134
},
}