具有连接表的实体核心映射实体类型 [英] Entity core Mapping entity types with join table
问题描述
我已经开始使用实体核心,但遇到了一个问题. 我在项目中使用了自动映射器,却不知道如何填充我的联接表(BookAuthor).
I've started using entity core and I ran into one problem. I'm using automapper in my project and don't know how to populate my join table(BookAuthor).
在MVC中,我使用过ICollections,但是实体核心尚不支持使用多对多关系实体,现在我必须使用连接表.
In MVC I worked with ICollections but entity core does not yet support working with many to many relationship entities and now I have to work with join table.
问题:如何将Bookview模型映射到Book? 我不知道应该如何处理我的BookAuthors列表.也许我不应该填充它?
Question: How can i map my Bookviewmodel to the Book? I don't know what should I do with my BookAuthors list. Maybe I shouldn't populate it?
我尝试了类似的方法,但是它不起作用.
I tried something like that but it's not working.
CreateMap<BookViewModel, Book>()
.ForMember(b => b.BookAuthors, opt => opt.MapFrom(b => b.Authors.Select(a => new BookAuthor
{
AuthorId = a.AuthorId
}
模型(为简洁起见,删除了某些属性)
public class Book
{
public int BookId { get; set; }
public List<BookAuthor> BookAuthors { get; set; }
}
public class Author
{
public int AuthorId { get; set; }
public string AuthorName { get; set; }
public List<BookAuthor> BookAuthors { 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; }
}
public class BookViewModel
{
public int BookId { get; set; }
public virtual List<AuthorViewModel> Authors { get; set; }
}
public class AuthorViewModel
{
public int AuthorId { get; set; }
public string AuthorName { get; set; }
}
public class Library : DbContext
{
public DbSet<Book> Books { get; set; }
public DbSet<Author> Authors { get; set; }
}
映射的工作版本
.ForMember(dto => dto.Authors, opt => opt.MapFrom(b => b.BookAuthors.Select(a=>a.Author).ToList()));
CreateMap<List<BookAuthor>, List<AuthorViewModel>>();
.PreserveReferences()//don't forget about this row or you will get an error
.ForMember(b => b.BookAuthors, opt => opt.MapFrom(b => b.Authors
.Select(a => new { b.BookId, Book = b, a.AuthorId, Author = a })));
推荐答案
以下是所需的映射配置:
Here is the desired mapping configuration:
CreateMap<Book, BookViewModel>()
// Book -> BookViewModel
.ForMember(b => b.Authors, opt => opt.MapFrom(b => b.BookAuthors
.Select(ba => ba.Author)))
.ReverseMap()
// BookViewModel -> Book
.PreserveReferences()
.ForMember(b => b.BookAuthors, opt => opt.MapFrom(b => b.Authors
.Select(a => new { b.BookId, Book = b, a.AuthorId, Author = a })))
;
CreateMap<Author, AuthorViewModel>()
// Author -> AuthorViewModel
.ReverseMap()
// AuthorViewModel -> Author
;
最重要的是要认识到AutoMapper不需要从MapFrom
返回的表达式的 type 来匹配目标的类型.如果不匹配,则AutoMapper将尝试使用相应的映射(如果有)将返回的类型映射到目标类型.这使您可以重用映射.
The most important thing is to realize that AutoMapper does not require the type of the returned expression from MapFrom
to match the type of the destination. If it doesn't match, then AutoMapper will try to map the returned type to the destination type using the corresponding mapping if any. This allows you to reuse the mappings.
为了将BookAuthor
转换为AuthorViewModel
,首先将其转换为Author
(通过简单地提取Author
属性),就像它是Author
的集合一样,然后让AM转换Author
到AuthorViewModel
使用相应的映射.
In order to convert BookAuthor
to AuthorViewModel
, you first convert it to Author
(by simply extracting the Author
property) like if it was a collection of Author
, and let AM convert the Author
to AuthorViewModel
using the corresponding mapping.
为了将AuthorViewModel
从BookViewModel.Authors
转换为BookAuthor
,首先将其转换为类似于BookAuthor
的无名类型,但相应的Book
和Author
属性类型为ViewModel
类型,并且让AM使用相应的映射将其转换为BookAuthor
. PreserveReferences()
用于避免由于循环参考模型而导致的堆栈溢出.
In order to convert AuthorViewModel
from BookViewModel.Authors
to BookAuthor
, you convert it first to anonomymous type similar to BookAuthor
, but with corresponding Book
and Author
property types being ViewModel
types and let AM convert it to BookAuthor
using corresponding mappings. PreserveReferences()
is used to avoid stack overflow due to circular reference model.
这篇关于具有连接表的实体核心映射实体类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!