我在我的域中有两个聚合根,因此有两个存储库。为了举例,我们将它们称为BookRepository和AuthorRepository。EF,知识库和跨越总体边界
我在设计一个MVC应用程序,一个页面必须显示一个包含作者列表的表格,每行显示作者的个人详细信息。在每行的末尾是一个小按钮,可以通过单击该按钮来展开该行并显示详细列出作者出版书籍的子表。
页面加载时,会执行一些ajax以从API控制器检索作者详细信息并在表中显示数据。作者对象中的每个属性几乎直接映射到列,但有一个例外,这就是我遇到问题的地方。我希望每行末尾的按钮都被禁用,当且仅当作者没有发布书籍时。这意味着每个作者记录必须返回一个布尔值,表明他们是否有任何已发布的书籍。
我的书库有这样几个方法:
public IEnumerable<Book> GetBooksForAuthor(int authorId);
public bool AnyBooksForAuthor(int authorId);
和My 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()
});
}
我不愿把这个就位这些原因:
- AuthorTableRowRepository是AuthorTableRows的存储库,但AuthorTable行不是域对象,也不是聚合根,因此不应有自己的存储库。
- 由于作者和书籍都是聚合根,所以我从作者实体中删除了“书籍”属性,因为我想要通过BookRepository检索书籍的唯一方法。这使HasBooks = a.Books.Any()不可能。不过,我不确定自己是否在这里强加了自己误导的最佳做法。通过AuthorRepository获取作者并通过其Books属性获取作者似乎是错误的,反之亦然,通过Book对象上的属性获取作者。穿越聚合根边界将是我认为的方式,我想呢?
其他人怎么解决这个问题?我的担心是否没有根据?我主要关心的是第一种方法的性能问题(应该是什么),但我想遵循Repository模式和DDD的最佳实践。
为什么downvotes ...?请解释一下,以便下次避免任何错误? – 2014-10-01 12:42:47