具有多对多关系问题的.Net Core Automapper
.Net Core Automapper with many to many relationship problem
我是 Automapper 的新手,我在映射具有多对多关系的 类 时遇到问题。
我想我需要像嵌套映射这样的东西,但文档对我来说似乎不是很清楚。我知道我在 AutoMapper 配置上做错了,但我不知道出了什么问题。
当我向数据库中添加一本新书时,我希望收到关于这本书和这本书的作者的信息。 (预期 JSON 结果如下)
我有以下 类:
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; }
}
DTO
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; }
}
图书控制器(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 // 我只附上了关于添加新书的部分。
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)));
}
我的问题是如何配置我的 AutoMapper Profiler 以获得下面的 JSON 结果?我对作者有意见。我仍然得到一个空列表。
{
"title": "sample title",
"isbn": "123-41-5-12311",
"category": "test",
"publisherId": 1,
"authors": [
{
"authorId": 43
},
{
"authorId": 45
},
{
"authorId": 134
},
}
您必须记住,automapper 依靠 属性 名称来识别可以完成哪些“automap”。如果您希望 Automapper 自动映射它们,则它们需要相同。
在您使用这行代码的情况下:
var bookToCreate = _mapper.Map<Book>(bookForNewDto);
您正在尝试将 BookForNewDto 实体映射到 Book 实体。您缺少的是 BookForNewDto 有一个名为 Authors 的 属性 而 Book 有一个名为 BooksAuthors 的 属性。 Automapper 永远不会知道 Authors 和 BooksAuthors 是它应该映射的内容。
因此,您需要在 Automapper 配置中使用 1 行代码指定此配置:
CreateMap<BookForNewDto, Book>() (this line is already present)
.ForMember(dto=>dto.BooksAuthors, opt => opt.MapFrom(x => x.Authors));
现在,如果您调试代码,您会看到 ICollection BooksAuthors 已从 BookForNewDto 映射。
您需要添加的下一个映射也是 AuthorForNewBookDto 和 BookAuthor,因为它们存在于您的 2 个实体中:请记住,如果您不指定它,automapper 会将 null 设置为您的值。
这里是最终的自动映射器配置:
CreateMap<BookForNewDto, Book>()
.ForMember(dto=>dto.BooksAuthors, opt => opt.MapFrom(x => x.Authors));
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)));
CreateMap<AuthorForNewBookDto, BookAuthor>();
CreateMap<BookAuthor, AuthorForNewBookDto>();
我是 Automapper 的新手,我在映射具有多对多关系的 类 时遇到问题。 我想我需要像嵌套映射这样的东西,但文档对我来说似乎不是很清楚。我知道我在 AutoMapper 配置上做错了,但我不知道出了什么问题。
当我向数据库中添加一本新书时,我希望收到关于这本书和这本书的作者的信息。 (预期 JSON 结果如下)
我有以下 类:
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; }
}
DTO
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; }
}
图书控制器(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 // 我只附上了关于添加新书的部分。
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)));
}
我的问题是如何配置我的 AutoMapper Profiler 以获得下面的 JSON 结果?我对作者有意见。我仍然得到一个空列表。
{
"title": "sample title",
"isbn": "123-41-5-12311",
"category": "test",
"publisherId": 1,
"authors": [
{
"authorId": 43
},
{
"authorId": 45
},
{
"authorId": 134
},
}
您必须记住,automapper 依靠 属性 名称来识别可以完成哪些“automap”。如果您希望 Automapper 自动映射它们,则它们需要相同。 在您使用这行代码的情况下:
var bookToCreate = _mapper.Map<Book>(bookForNewDto);
您正在尝试将 BookForNewDto 实体映射到 Book 实体。您缺少的是 BookForNewDto 有一个名为 Authors 的 属性 而 Book 有一个名为 BooksAuthors 的 属性。 Automapper 永远不会知道 Authors 和 BooksAuthors 是它应该映射的内容。 因此,您需要在 Automapper 配置中使用 1 行代码指定此配置:
CreateMap<BookForNewDto, Book>() (this line is already present)
.ForMember(dto=>dto.BooksAuthors, opt => opt.MapFrom(x => x.Authors));
现在,如果您调试代码,您会看到 ICollection BooksAuthors 已从 BookForNewDto 映射。
您需要添加的下一个映射也是 AuthorForNewBookDto 和 BookAuthor,因为它们存在于您的 2 个实体中:请记住,如果您不指定它,automapper 会将 null 设置为您的值。
这里是最终的自动映射器配置:
CreateMap<BookForNewDto, Book>()
.ForMember(dto=>dto.BooksAuthors, opt => opt.MapFrom(x => x.Authors));
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)));
CreateMap<AuthorForNewBookDto, BookAuthor>();
CreateMap<BookAuthor, AuthorForNewBookDto>();