我的域中有两个聚合根,因此有两个存储库。为了举例,我们将它们称为BookRepository和AuthorRepository。
我正在设计一个MVC应用程序,一个页面必须显示一个包含作者列表的表格,每一行都显示作者的个人详细信息。在每行的末尾是一个小按钮,可以单击该按钮以展开行并显示详细说明作者已出版书籍的子表。
当页面加载时,执行一些ajax以从API控制器检索作者详细信息并在表中显示数据。 Author对象中的每个属性几乎都直接映射到一个列,但有一个例外,这就是我遇到问题的地方。我希望禁用每行末尾的按钮,当且仅当作者没有已发布的书籍时。这意味着必须在每个作者记录中返回一个布尔值,表明他们是否有任何已出版的书籍。
我的图书资料库有以下两种方法:
public IEnumerable<Book> GetBooksForAuthor(int authorId);
public bool AnyBooksForAuthor(int authorId);
我的Book类有一个名为AuthorId的属性,所以我可以通过调用
来检索一本书的作者authorRepository.GetById(book.AuthorId);
我的问题是,为了为我上面提到的表创建一行,我需要像这样创建它:
IEnumerable<Author> authors = authorRepository.GetAll();
foreach (Author author in authors)
{
yield return new AuthorTableRow
{
Name = author.Name,
Age = author.Age,
Location = author.PlaceOfResidence.Name,
HasBooks = this.bookRepository.AnyBooksForAuthor(author.Id)
};
}
上面的代码似乎是正确的,但是在为每个作者调用this.bookRepository.AnyBooksForAuthor(author.Id)时会有相当大的性能损失,因为它每次都会执行数据库调用。
理想情况下,我想我想要一个可以执行以下操作的AuthorTableRowRepository:
public IEnumerable<AuthorTableRow> GetAll()
{
return from a in this.dbContext.Authors
select new AuthorTableRow
{
Name = a.Name,
Age = a.Age,
Location a.PlaceOfResidence.Name
HasBooks = a.Books.Any()
});
}
由于以下原因,我不愿意这样做:
其他人如何解决这个问题?我的担忧没有根据吗?我最关心的是第一种方法中的(应该是什么)性能,但我想坚持使用Repository模式和DDD的最佳实践。
答案 0 :(得分:0)
我会坚持第一种方法,但尝试在bookrepository方法中优化一些东西。例如,您可以一次性加载此信息,并使用内存中查找来加快速度。像这样你需要2个查询,而不是每个作者1个查询。
答案 1 :(得分:0)
我最终解决这个问题的方法是从数据库中的视图创建一个实体。我命名了实体&#39; AuthorSummary&#39;,并创建了一个不包含任何Add()方法的AuthorSummaryRepository,只是检索方法。