我应该如何拥有存储库以及如何进行交互?

时间:2010-12-27 10:41:38

标签: design-patterns data-access-layer repository-pattern

阅读this question及其答案以及其他一些资源后,我认为我的应用程序有3个聚合根,因此应该有3个匹配的存储库,但我不确定当我使用时如何使用存储库需要获取其他聚合根之一的数据。

Le看一个例子。想象一下更简单的Stack Overflow版本,其中包含用户,标签和问题的概念。在我看来,这些都是聚合根,因为我们需要列出并查询它们,因此每个都应该拥有它自己的存储库。

鉴于您查看用户个人资料的情况,并且您还想显示用户发布的所有问题,是否应使用QuestionsRepository内的UsersRepository来填充一个user.Questions数组?

我认为这个问题更多的是关注点分离,但它解决了存储库应该如何交互的问题。在我看来,在存储库之间生成循环引用变得非常容易。

E.g。 UsersRepositoryQuestionsRepositiory中提取所有用户的问题,每个问题使用UsersRepository实例获取用户数据,依此类推。

现在让我们采取相反的观点(我刚才谈到了)。要列出所有问题,我们将使用QuestionsRepository并调用GetAll()方法(或类似方法)。在此清单中,我们希望显示用户信息,以便我们从数据库中获取它。

理想情况下,在这种情况下,我们希望执行从问题到用户的连接,而不是获取所有问题并迭代它们每次获取用户,给我们一个N + 1的情况和一堆不必要的旅行数据库。

是否允许QuestionsRespository实例化Users来执行加入?或是否必须使用UsersRepository,以防止单次访问数据库。

显而易见的是,您可以获得标签,并且需要显示所有问题及其用户。 TagsRepository是否应使用QuestionsRespository来获取tag LIKE 'tag-name'所有问题,UsersRepository又使用TagsRepository来获取每个问题的用户信息?或者Questions是否允许实例化Users和{{1}}来填充对象图?

1 个答案:

答案 0 :(得分:2)

尝试仅考虑使用存储库来更改数据(命令)并为只读的查询操作提供单独的服务/“读取存储库” - 并绕过通常的存储库,直接进入数据库,使用以下方式读取数据针对特定情况优化的SQL查询。当您需要使用存储库轻松获取的信息(即显示有关一个用户的详细信息)时,我仍然会使用通常的存储库,但是对于更复杂的方案使用只读服务(即屏幕显示一些汇总数据的摘要)更复杂的聚合根源)。但请确保始终使用存储库来更改数据。

你可以更进一步,看看一个名为CQRS的模式 - 命令查询责任隔离(www.cqrsinfo.com),它基本上是完全将应用程序状态的应用程序部分与读取的应用程序部分分开/查询应用程序状态),虽然需要一些时间来掌握它。 (请注意,CQRS与CQS不同)。