C# 林克。链接是否可能避免在大型数据集上进行连接?

C# 林克。链接是否可能避免在大型数据集上进行连接?,c#,entity-framework-core,repository-pattern,unit-of-work,C#,Entity Framework Core,Repository Pattern,Unit Of Work,我正在使用存储库/工作单元模式构建一个n层应用程序,但是我在读取相关实体的属性时遇到了问题,因为它们没有加载。我已经确定问题是由延迟加载引起的。一个简化的示例可能是尝试在下面的代码中检索一本书的作者,因为该书的Author和Publisher属性都为null 一般来说,我对延迟加载很感兴趣,因为这(据我所知)会减少传输的数据量。这对我来说特别有趣,因为我并不总是在我的Razor页面中使用所有属性或集合。 也就是说,我不确定这是一个好的策略,并且正在考虑改变整个体系结构,使其脱离存储库/工作单元模

我正在使用存储库/工作单元模式构建一个n层应用程序,但是我在读取相关实体的属性时遇到了问题,因为它们没有加载。我已经确定问题是由延迟加载引起的。一个简化的示例可能是尝试在下面的代码中检索一本书的作者,因为该书的Author和Publisher属性都为null

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

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;}
}
上述想法是为了减少传输的数据量,还是我完全误解了

我不太喜欢在每个Razor页面中注入
DBContext
,这就是为什么我首先选择存储库/工作单元设计模式。。如果我仍然需要延迟加载,那么我应该尝试DDD模式吗


关于如何继续,有什么想法吗?

为了减少传输的数据量,您必须减少。包括,所以请这样提问(这只是想法):

首先,创建只包含所需字段的类:

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();
在这种情况下,您可以使用同一类书而不是BookInfo:

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

}).ToArrayAsync();
}

Include
仅用于快速加载,不生成连接。这些是由ORM本身的实体之间的关系生成的。至于存储库和UoW,您不需要它们。DbSet已经是一个存储库,DbContext已经是一个工作单元。如果您尝试重新实现这些模式,您只会创建bug并破坏UoW功能。由于延迟加载,这通常会增加加载的数据和N+1问题带来的开销。与执行1个返回所有必要数据的查询不同,您有1个只返回根对象的查询和N个在访问每个对象时加载每个对象的查询。除了@PanagiotisKanavos应该真正理解的评论之外,问题的这一部分:“对我来说特别有趣,因为我并不总是在我的Razor页面中使用所有属性或集合”告诉我,你不应该使用延迟加载,也不应该使用
包含
,而是使用必要的数据创建ViewModels,并选择
而不是只允许您加载所需属性的
。没有理由加载整个实体。没有理由使用2000年引入的模式来加载J2EE中的整个实体。将DbContext视为DDD中有界上下文的数据服务。没有理由为整个应用程序使用一个DbContext来映射整个数据库。创建专门的存储库以方便访问专门的DbContext是有意义的。不过,通用上下文是无用的。DbSet已经提供了
.Set()
只能在实体已经配置的情况下使用。在这种情况下,为什么不直接使用
Books
属性呢?使用
Set()。我没有看到完整的dbcontext,这就是我使用Set的原因。但通常我会用书。
public partial class Book 
{
 [NotMapped]
  public string AuthorName {get; set;}
[NotMapped]
 public string PublisherName {get; set;}
}
.Select ( b => new  Book {
Id = b.Id,
AuthorName=b.Author.Name,
PublisherName=b.Publisher.Name,
....and so on

}).ToArrayAsync();
}