Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework EF、存储库和跨聚合边界_Entity Framework_Repository_Domain Driven Design_Aggregateroot - Fatal编程技术网

Entity framework EF、存储库和跨聚合边界

Entity framework EF、存储库和跨聚合边界,entity-framework,repository,domain-driven-design,aggregateroot,Entity Framework,Repository,Domain Driven Design,Aggregateroot,我的域中有两个聚合根,因此有两个存储库。为了举例,我们将它们称为BookRepository和AuthorRepository 我正在设计一个MVC应用程序,一个页面必须显示一个包含作者列表的表格,每一行显示作者的个人详细信息。每行末尾都有一个小按钮,单击该按钮可以展开该行,并显示一个子表,详细说明作者出版的书籍 加载页面时,会执行一些ajax,从API控制器检索作者详细信息,并在表中显示数据。Author对象中的每个属性几乎直接映射到一列,只有一个例外,这就是我的问题所在。我想禁用每行末尾的按

我的域中有两个聚合根,因此有两个存储库。为了举例,我们将它们称为BookRepository和AuthorRepository

我正在设计一个MVC应用程序,一个页面必须显示一个包含作者列表的表格,每一行显示作者的个人详细信息。每行末尾都有一个小按钮,单击该按钮可以展开该行,并显示一个子表,详细说明作者出版的书籍

加载页面时,会执行一些ajax,从API控制器检索作者详细信息,并在表中显示数据。Author对象中的每个属性几乎直接映射到一列,只有一个例外,这就是我的问题所在。我想禁用每行末尾的按钮,如果且仅当作者没有出版书籍时。这意味着每个作者记录都必须返回一个布尔值,指示他们是否有任何已出版的书籍

My book repository有以下几种方法:

public IEnumerable<Book> GetBooksForAuthor(int authorId);

public bool AnyBooksForAuthor(int 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)
    };
}
我的问题是,为了为前面提到的表创建一行,我需要这样创建它:

public IEnumerable<Book> GetBooksForAuthor(int authorId);

public bool AnyBooksForAuthor(int 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)
    };
}
IEnumerable authors=authorRepository.GetAll();
foreach(作者中的作者)
{
返回新的authotableRow
{
Name=author.Name,
年龄=作者。年龄,
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()
           });
}
public IEnumerable GetAll()
{
从this.dbContext.Authors中的
选择新的AuthorTableRow
{
Name=a.Name,
年龄,
位置a.PlaceOfResidence.Name
HasBooks=a.Books.Any()
});
}
出于以下原因,我犹豫是否将其落实到位:

  • AuthorTableRowRepository是AuthorTableRows的存储库,但AuthorTableRow不是域对象,也不是聚合根,因此不应该有自己的存储库
  • 由于Author和Book都是聚合根,因此我从Author实体中删除了“Books”属性,因为我希望通过BookRepository检索图书的唯一方法。这使得HasBooks=a.Books.Any()不可能。不过,我不确定我是否在这里强加了自己被误导的最佳实践。通过AuthorRepository获取作者,然后通过其Books属性获取书籍,这似乎是错误的,反之亦然,通过Book对象上的属性获取作者,这似乎是错误的。我想,跨越聚合根边界将是我将其命名的方式

其他人会如何解决这个问题?我的担心是没有根据的吗?我最关心的是第一种方法对性能的影响(应该是什么),但我希望坚持存储库模式和DDD的最佳实践。

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

我最终解决这个问题的方法是从数据库中的视图创建一个实体。我将实体命名为“AuthorSummary”,并创建了一个AuthorSummary存储库,其中不包含任何Add()方法,只包含检索方法。

如何优化bookrepository方法?这是一个非常直截了当的问题。任何()对数据库的查询,我都不确定我还能做些什么来优化它?好吧,如果bookrepository会有一个按作者列出的书籍数量的内存列表,那么您只需在循环之前初始化该列表,如下所示<代码>this.bookRepository.LoadBooksByAuthor();IEnumerable authors=authorRepository.GetAll();foreach(Author-Author-in-authors){yield return new AuthorTableRow{Name=Author.Name,Age=Author.Age,Location=Author.PlaceOfResidence.Name,HasBooks=this.booksrepository.AnyBooksForAuthor(Author.Id)//此调用不进入数据库,只是内存中的查找;}如果图书存储库有数百万本书要加载,这真的更好吗?bookRepository也无法加载表的一个子集,因为在执行author查询之前,它不知道您需要哪些书籍的信息?事实上,我不会加载所有书籍。。。只有按作者列出的图书总量。此内存列表将记录每个作者。。。如果这是不可接受的,你就应该考虑实用,让AuthoSooStk把书的数量和每个作者的记录一起归还。为什么要投票?请解释一下,以便下次我能避免任何错误?