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();
}
我正在使用 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();
}