LINQ。链接 .includes 是否可以避免连接大型数据集?

LINQ. Is linking .includes possible to avoid joins on large datasets?

我正在使用 Repository/Unit 工作模式构建一个 n 层应用程序,但我无法读取相关实体的属性,因为它们没有加载。我已经确定问题是由延迟加载引起的。一个简化的例子可能是尝试在下面的代码中检索一本书的作者,因为 Book 的 Author 和 Publisher 属性都是空的。

总的来说,我对延迟加载很感兴趣,因为这(据我所知)应该减少传输的数据量。这对我来说特别有趣,因为我并不总是在我的 Razor 页面中使用所有属性或集合。 也就是说,我不确定这是一个好的策略,并且正在考虑改变整个架构,使其远离 Repository/Unit 工作模式。我还没有决定。

public Author 
{
    public int Id {get; set;}
    public string Name {get; set;}
    public ICollection<Book> Books {get; set;}
    public ICollection<Publisher> Publishers {get; set;}
}

public Book
{
    public int Id {get; set;}
    public string Title {get; set;}
    public int AuthorId {get; set;}
    public ICollection<Author> Authors {get; set;}
    public Publisher Publisher {get; set;}
}

public Publisher
{
    public int Id {get; set;}
    public string Name {get; set;}
    public ICollection<Book> Books {get; set;}
    public ICollection<Author> Authors {get; set;}
}

回到问题。首先,我尝试应用 .Include(p=>p.Author).Load(p=>p.Author),但我意识到在 .ToListAsync() 之后这是不可能的,我在通用存储库的“GetAllAsync()”方法中调用了它。

现在我正在考虑将 DbContext 直接注入我的 Razor 页面或服务层,然后链接 Include() 调用 e.i.

_context.DBSetBooks<Book>.Include(p => p.Publisher).Where(p => p.Publisher.Name == "Manning").Include(p => p.Author);

上面的想法是为了减少传输的数据量,还是我完全误解了?

我不太喜欢在每个 Razor 页面中注入 DBContext - 这就是为什么我首先选择工作设计模式 Repository/Unit 的原因。如果我仍然想要延迟加载应该然后我尝试使用 DDD 模式?

关于如何进行的任何想法?

要减少传输的数据量,您必须减少 .include,因此请这样查询(这只是想法):

首先创建只有您需要的字段的 class:

public class BookInfo
{
 public int Id {get; set;}
  public string AuthorName {get; set;}
 public string PublisherName {get; set;}
.... and so on
}

使用如下查询获取图书列表:

 var books = await _context.Set<Book>()
.Where(p => p.Publisher.Name == "Manning")
.Select (b =>  new  BookInfo {
Id = b.Id,
AuthorName=b.Author.Name,
PublisherName=b.Publisher.Name,
....and so on

}).ToArrayAsync();

另一种可能性是,您将部分 class 图书放在一个单独的文件中,其中包含额外的字段,例如

public partial class Book 
{
 [NotMapped]
  public string AuthorName {get; set;}
[NotMapped]
 public string PublisherName {get; set;}
}

在这种情况下,您可以使用相同的 class Book 而不是 BookInfo:

.Select ( b => new  Book {
Id = b.Id,
AuthorName=b.Author.Name,
PublisherName=b.Publisher.Name,
....and so on

}).ToArrayAsync();
}