簡體   English   中英

在Entity Framework Core中加載嵌套屬性

[英]Loading nested properties in Entity Framework Core

有什么辦法可以避免在EF Core中使用Include和ThenInclude嗎? 我有這些模型和dtos:

書籍:

  public partial class Book
   {
      public Book()
   {
     BookAuthors = new HashSet<BookAuthor>();
     BookCategories = new HashSet<BookCategory>();
     Reviews = new HashSet<Review>();
   }

  public int BookId { get; set; }
  public string Title { get; set; }
  ...
  public string ImageUrl { get; set; }

  public ICollection<BookAuthor> BookAuthors { get; set; }
  public ICollection<BookCategory> BookCategories { get; set; }
  public ICollection<Review> Reviews { get; set; }
 }

  public class BookDto
 {
   public int BookId { get; set; }
   public string Title { get; set; }
   ...
   public string ImageUrl { get; set; }
   public IList<AuthorDto> Authors { get; set; }
   public IList<CategoryDto> Categories { get; set; }
   public IList<ReviewDto> Reviews { get; set; }
}

對於作者:

public partial class Author
{
    public Author()
    {
        BookAuthors = new HashSet<BookAuthor>();
    }
    public int AuthorId { get; set; }
    public string AuthorName { get; set; }
    ...
    public ICollection<BookAuthor> BookAuthors { get; set; }
}

public class AuthorDto
{
  public int AuthorId { get; set; }
  public string AuthorName { get; set; }
  ...
  public IList<BookDto> Books { get; set; }
}

對於類別:

 public partial class Category
 {
    public Category()
    {
        BookCategories = new HashSet<BookCategory>();
    }

    public int CategoryId { get; set; }
    public string CategoryName { get; set; }
    public string Description { get; set; }
    public ICollection<BookCategory> BookCategories { get; set; }
  }

public class CategoryDto
{
  public int CategoryId { get; set; }
  public string CategoryName { get; set; }
  public string Description { get; set; }
  public IList<BookDto> Books { get; set; }
}

並審查:

public partial class Review
{
    public int ReviewId { get; set; }
    public int BookId { get; set; }
    public int UserId { get; set; }
    public DateTime? Date { get; set; }
    public string Comments { get; set; }
    public decimal? Rating { get; set; }
    public Book Book { get; set; }
    public User User { get; set; }
}

public class ReviewDto
{
    public int ReviewId { get; set; }
    public int BookId { get; set; }
    public int UserId { get; set; }
    public DateTime? Date { get; set; }
    public string Comments { get; set; }
    public decimal? Rating { get; set; }
    public Book Book { get; set; }
    public User User { get; set; }
}

我有這個 :

public IEnumerable<Book> GetAll()
{
  var books = _context.Book
        .Include(e => e.BookAuthors)
        .ThenInclude(a => a.Author)
        .Include(c => c.BookCategories)
        .ThenInclude(categ => categ.Category)
        .Include(r => r.Reviews)
        .AsNoTracking()
        .ToList();
  return books;
}

然后在作者:

public IEnumerable<Author> GetAll()
{
  var authors = _context.Author
        .Include(e => e.BookAuthors)
        .ThenInclude(b => b.Book)
        .ToList();
  return authors;
}

public Author GetById(int id)
{
  return _context.Author.Include("BookAuthors.Book").SingleOrDefault(x => 
  x.AuthorId == id);
}

在書籍和作者之間,在書籍和類別之間,我有多對多的關系,在評論和書籍之間,是一對多的關系。 我之所以需要這樣做,是因為在書籍清單上,我還會顯示作者的姓名,在作者詳細信息頁面上,我也會顯示他的書籍,依此類推。 我也在使用AutoMapper和DTO。

對於具有返回數據的Categories,Reviews..my json來說,它變得非常大,並且由於要使用嵌套結構,因此需要花費大量時間將數據加載到頁面中。 這樣做的最佳解決方案是什么?

有一種方法可以快速加載。 我嘗試了GroupJoin(expression).SelectMany(...)。 這將使您加載到一個級別,從而避免循環引用。 我將向您展示如何將其歸檔,但會附帶您的模型。

你有:

 var books = _context.Book
    .Include(e => e.BookAuthors)
    .ThenInclude(a => a.Author)
    .Include(c => c.BookCategories)
    .ThenInclude(categ => categ.Category)
    .Include(r => r.Reviews)
    .AsNoTracking()
    .ToList();
 return books;

順便說一句,您沒有放置BookAuthors模型。 因此,我假設其結構為:

var books = _context.Authors
        .GroupJoin(_context.Book,
                    t1 => new { IdAuthor = (Guid)t1.Id }, //where t1 = Authors, you should have IdAuthor in Book.
                    a => new { IdAuthor = (Guid)a.IdAuthor },     //where a = Book
                    (t1, a_join) => new { t1, a_join })
        .SelectMany(t1 => t1.a_join.DefaultIfEmpty(), (t1, a) => new { t1, a }) //.DefaultIfEmpty() = LEFT JOIN
        .Select(x => new AuthorBooksDTO
        {
            IdAutor = t1.t1.Id //please navegate t1 till VS shoows you which model is
            Books = t1.t1.a_join.toList() //navegate t1. a_join will be the list of books.
            ....
        })
        .ToList();

當然,構建需要花費更多時間,但是性能卻得到了驚人的提高。 讓我們知道它是否適合您。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM