【发布时间】:2011-07-06 16:42:14
【问题描述】:
我目前几乎为数据库中的每个表都有一个存储库,并且希望通过将它们减少到仅聚合根来进一步使自己与 DDD 保持一致。
假设我有以下表格,User 和 Phone。每个用户可能拥有一部或多部手机。如果没有聚合根的概念,我可能会这样做:
//assuming I have the userId in session for example and I want to update a phone number
List<Phone> phones = PhoneRepository.GetPhoneNumberByUserId(userId);
phones[0].Number = “911”;
PhoneRepository.Update(phones[0]);
聚合根的概念在纸面上比在实践中更容易理解。我永远不会拥有不属于用户的电话号码,那么取消 PhoneRepository 并将与电话相关的方法合并到 UserRepository 是否有意义?假设答案是肯定的,我将重写之前的代码示例。
我是否允许在 UserRepository 上有一个返回电话号码的方法?或者它是否应该总是返回对用户的引用,然后通过用户遍历关系以获取电话号码:
List<Phone> phones = UserRepository.GetPhoneNumbers(userId);
// Or
User user = UserRepository.GetUserWithPhoneNumbers(userId); //this method will join to Phone
无论我以何种方式获取手机,假设我修改了其中一部,我该如何更新它们?我有限的理解是根目录下的对象应该通过根目录更新,这将引导我走向下面的选择#1。尽管这可以与 Entity Framework 完美配合,但这似乎非常不具描述性,因为阅读代码我不知道我实际上在更新什么,即使 Entity Framework 会密切关注图表中更改的对象。
UserRepository.Update(user);
// Or
UserRepository.UpdatePhone(phone);
最后,假设我有几个与任何东西没有真正关联的查找表,例如CountryCodes、ColorsCodes、SomethingElseCodes。我可能会使用它们来填充下拉菜单或出于其他任何原因。这些是独立的存储库吗?它们可以组合成某种逻辑分组/存储库,例如CodesRepository?或者这违反了最佳实践。
【问题讨论】:
-
确实是一个非常好的问题,我一直在为自己苦苦挣扎。似乎是没有“正确”解决方案的权衡点之一。虽然在我写这篇文章时可用的答案很好并且涵盖了大多数问题,但我觉得它们没有提供任何“最终”解决方案.. :(
-
我听到你的声音,对于一个人可以获得的“正确”解决方案有多接近是没有限制的。我想我们必须尽力而为,直到我们学会更好的方法:)
-
+1 - 我也在为此苦苦挣扎。在我为每个表设置单独的存储库和服务层之前。我开始在有意义的地方组合这些,但最终我得到了一个包含超过 1k 行代码的 repo 和服务层。在我最新的应用程序切片中,我已经备份了一点,只将密切相关的概念放在同一个 repo/service 层中,即使该项目是依赖的。例如 - 对于博客,我将 cmets 添加到 post repo 聚合中,但现在我已将它们分离为单独的评论 repo/service。
标签: c# asp.net entity-framework entity-framework-4 domain-driven-design