EF,存储库和跨越聚合边界

时间:2014-09-19 17:20:06

标签: entity-framework repository domain-driven-design aggregateroot

我的域中有两个聚合根,因此有两个存储库。为了举例,我们将它们称为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()
           });
}

由于以下原因,我不愿意这样做:

  • AuthorTableRowRepository是AuthorTableRows的存储库,但AuthorTable行不是域对象,也不是聚合根,因此不应该有自己的存储库。
  • 由于作者和书籍都是聚合词根,我删除了&#34;书籍&#34;来自Author实体的属性,因为我想要通过BookRepository检索书籍的唯一方法。这使得HasBooks = a.Books.Any()成为不可能。我不确定我是否在这里强加我自己误入歧途的最佳做法。通过AuthorRepository获取作者然后通过其Books属性获取Books似乎是错误的,反之亦然,通过Book对象上的属性获取作者。我想,越过聚合根边界将是我称之为的方式吗?

其他人如何解决这个问题?我的担忧没有根据吗?我最关心的是第一种方法中的(应该是什么)性能,但我想坚持使用Repository模式和DDD的最佳实践。

2 个答案:

答案 0 :(得分:0)

我会坚持第一种方法,但尝试在bookrepository方法中优化一些东西。例如,您可以一次性加载此信息,并使用内存中查找来加快速度。像这样你需要2个查询,而不是每个作者1个查询。

答案 1 :(得分:0)

我最终解决这个问题的方法是从数据库中的视图创建一个实体。我命名了实体&#39; AuthorSummary&#39;,并创建了一个不包含任何Add()方法的AuthorSummaryRepository,只是检索方法。