问题标签 [aggregateroot]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
asp.net-mvc - 使用 EF 存储库从聚合根目录中删除子对象
我原来的问题在这里。
下面是我更新的代码。
当工作单元尝试提交时,它会产生以下错误消息。
我知道当我使用 StockTransfer.RemoveItem() 时,它会从集合中删除项目,但会将记录保留在数据库中,这就是我收到错误的原因。
有没有办法从聚合根中删除子对象并保留聚合根?
domain-driven-design - 试图识别汽车租赁域的聚合根
我正在尝试使用汽车租赁网站的域来研究 ddd 的某些方面。
用户/客户从起点和终点站以及时间段中选择汽车。
价格计算取决于各种因素,如付款方式、时间、汽车分类等。数据是从一个子系统中检索的,该子系统的数据访问策略与应用程序的其余部分不同。
该领域有几个参与者,如车站服务、呼叫中心......
有界上下文的想法是
- 公司(员工、汽车、车站)
- 预订(预订,预订请求流程的模型)
- 定价(价格模型)
- 计费(租金计费、职位、客户)
在定义有界上下文之后,我不确定每个的聚合根是否正确。我的想法是
- 公司:他们三个
- 预订:预订(访问帐单、汽车和客户)
- 定价:关税矩阵
- 计费:客户(访问预订、计费)
如果需要,我可以添加一些类图来显示不同的有界上下文。如果需要更多信息,类图或这应该迁移到其他部分随时询问/执行。
entity-framework-4.1 - 子修改时更新聚合根
我正在使用 EF 4.2,其中相关位如下所示:
如果我拉回一个特定的用户,然后更新关联的会员对象(比如更新失败的密码计数),会员对象就会更新,但用户也会更新,尽管没有更新用户属性。这是因为 Membership 对象已经触发了某种更改的事件并且它冒泡到父用户?
即使我加载用户然后使用 _context.Memberships.Find(userId) 而不是仅使用 user.Membership 导航属性获取成员资格,也会发生这种情况。我猜在上下文图中这两个是等价的?
当我使用修改日期的计算值列时,有什么方法可以阻止更新用户对象,我希望在更改子实体时不更新它。理想情况下,我想拉回 User 对象,而不仅仅是查询 Membership DbSet,因为我也想读取一些 User 属性。
在父用户表上触发的 SQL 是:
asp.net-mvc - 如何使用 EF 实现聚合根存储库和添加子实体
我正在开发一个 MVC 应用程序。我有一个域模型,我使用存储库模式进行数据访问和实体框架代码优先。我还有一个 UnitOfWork 类,我通过它调用存储库操作。
我的问题主要出现在我尝试利用聚合根并通过其父存储库处理子对象时。
这就是问题所在:父类“供应商”与部门有几个合同。在这种情况下,我选择让合同成为供应商的孩子。
要添加新合同,我需要添加一个方法来在我的 SupplierRepository 中添加合同,我尝试了:
我也试过:
当我打电话时
我收到一个错误告诉我:
一个实体对象不能被多个 IEntityChangeTracker 实例引用
UnitOfWork 实例化我的 DbContext (myDbContext) 和 SupplierRepository 并调用 myDbContext.Save()
- 为什么我会出现这种行为
- 我应该如何实现聚合根存储库(子对象的 CRUD 操作)
据我了解,我应该在存储库中有一个方法来接受合同并添加它,而不是在我的 MVC 应用程序的控制器中执行此操作,但我似乎没有让它工作。
我看过很多关于聚合根的信息,但没有关于如何实现它的示例。
谢谢。
解决方案:
好吧,我终于想通了。
所以这不是存储库的问题,但是新的 SupplierContract 向存储库查询创建它的用户实体(通过扩展方法)。显然这个上下文没有处理,因此当我实例化它以保存合同实体时,我有两个当前的 DbContexts。
希望有人通过阅读本文来节省时间。
我通过在 SupplierRepository 中这样做解决了聚合根存储库:
并调用 UnitOfWork.Save() 方法。
c# - 如何识别域模型中的聚合根?
在涉足领域驱动设计时,我遇到了关于如何在我的领域模型中识别聚合根的情况。
我有以下三个类,建模一个简单的待办事项列表:
关于模型,我可以说明以下内容:
- 更新仅存在于任务的上下文中。
- 任务仅存在于列表的上下文中。
因此,列表似乎是唯一的聚合根。(实际上,我的数据访问层只允许加载/保存 List 对象。)但是我看不到如何将我的 Task 类中当前存在的 UI 干净地推送到 List 类。目前我的 List 类正在分发对 Task 对象的引用,允许调用者修改它们。
这是否意味着 Task 也是一个聚合根,即使它的存在依赖于包含列表?
提前致谢。
asp.net-mvc - EF 删除子对象
从父实体集合中删除子实体时,我注意到 EF 将子实体状态设置为修改而不是删除。
实体对象管理器中是否有另一个属性将其设置为删除?
下面是我在 EF 存储库中的 Save 方法中使用的代码,用于查找任何已修改的子项,然后将其删除。
我遇到的问题是试图检测更新和删除之间的区别,因为两者的状态都设置为修改。目前,当我更新记录时,它正在删除该项目。我可以在两种状态之间进行检测吗?
domain-driven-design - 实施 Udi 的获取策略 - 我如何搜索?
背景
Udi Dahan 建议将获取策略作为用于数据访问的有用模式。我同意。
这个概念是使角色明确。例如,我有一个聚合根 - 客户。我希望客户在我的应用程序的几个部分中 - 可供选择的客户列表,客户详细信息的视图,并且我想要一个按钮来停用客户。
似乎 Udi 会为这些角色中的每一个建议一个界面。所以我有ICustomerInList
非常基本的细节,ICustomerDetail
其中包括最近购买的 10 种产品,并且IDeactivateCustomer
有一种方法可以停用客户。每个接口都暴露了我的客户聚合根,以便在每种情况下完成工作。我的客户聚合根实现了所有这些接口。
现在我想为每个角色实现一个获取策略。每种策略都可以将不同数量的数据加载到我的聚合根中,因为它将位于只公开所需信息位的接口后面。
实现这部分的一般方法是询问服务定位器或其他样式的依赖注入。例如,此代码将获取您想要的接口ICustomerInList
,并找到一个获取策略来加载它(IStrategyForFetching<ICustomerInList>
)。这个策略是由一个类实现的,该类知道只加载具有 ICustomerInList 接口所需的信息位的客户。
到目前为止,一切都很好。
问题
您传递给服务定位器或IStrategyForFetching<ICustomerInList>
. 我看到的所有示例都仅通过已知 ID 选择一个对象。这种情况很简单,调用代码通过这个id,会得到具体的接口。
如果我想搜索怎么办?或者我想要客户列表的第 2 页?现在我想传递更多获取策略所需的术语。
可能的解决方案
我见过的一些示例使用谓词 - 如果特定聚合根应该是结果集的一部分,则返回 true 或 false 的表达式。这在条件下工作得很好,但是让前 n 个客户回来而不是更多呢?或者获取搜索结果的第 2 页?或者结果如何排序?
我的第一反应是开始向我的IStrategyForFetching<ICustomerInList>
It now添加泛型参数IStrategyForFetching<TAggregateRoot, TStrategyForSelecting, TStrategyForOrdering>
。这很快变得复杂而丑陋。不同的存储库使情况更加复杂。一些存储库仅在使用特定策略进行选择时提供数据,有些仅提供某些类型的排序。我希望能够灵活地实现可以采用排序功能的通用存储库以及仅返回以特定方式排序的聚合根的专用存储库。
听起来我应该应用开始时使用的相同模式 - 如何明确角色?我是否应该使用有效负载 Y(搜索/排序参数)实施获取 X(聚合根)的策略?
编辑 (2012-03-05)
如果我不是每次都返回聚合根,这一切仍然有效。如果每个接口由不同的 DTO 实现,我仍然可以使用 IStrategyForFetching。这就是这种模式强大的原因 - 获取和返回的内容不必以任何方式映射到聚合根。
我最终使用了IStrategyForFetching<TEntity, TSpecification>
. TEntity 是我想要得到的东西,TSpecification 是我想要得到它的方式。
entity-framework - 如何更新聚合根中的孙子
我首先使用 EF 代码和延迟加载。
我的问题与如何有效地更新孙集合中的实体有关。首先,我担心这会在数据库中进行很多并不真正需要的调用。但是,如果我的域类不关心持久性,我看不出另一种方法来做到这一点。
这是课程:
供应商是聚合根。所以我有一个关于供应商的方法是 ChangeDeliveryContract,它对应于现实世界中会发生的事情。
我使用 MVC,所以程序看起来像: public ActionResult Update (DeliveryContract changedDc, int supplierId)
首先,问题在于 ChangeDeliveryContract。我无法让它工作。另外,我觉得像我一样通过集合进行查询可能效率低下。第三,映射30+属性也感觉有点不对劲。
你们是怎么做的,这里有没有最佳实践。
java - DDD:跨聚合维护约束
仍在阅读和学习 DDD 并尝试将其应用到我正在从事的项目中。我仍在尝试绕过聚合并遇到一个有趣的问题。
假设我有 2 个聚合,1 个具有根的帐户实体,另一个具有根的用户实体。
没有用户就无法创建帐户,但用户可以,这就是为什么它们都充当自己聚合的根。请注意,他们的聚合包括其他实体,但这对我的问题并不重要。
一些业务规则: 1) 创建帐户时,必须与用户关联。如果用户不存在,则必须先创建它。
2) 当一个帐户被删除时,其关联的用户也必须被删除。
3) 创建用户时,不需要与帐户关联。
3) 当一个用户被删除时,如果它与一个帐户相关联,它也必须被删除。
由于 Account 和 User 形成了它们自己的聚合,因此可能会有它们自己的 Repositories。这意味着标准的添加、删除、查找和删除方法将由每个存储库定义。
因此,鉴于这些情况,完成以下任务的最佳方法是什么: 1) 创建帐户时,我想我会在其用户属性上调用一个方法来验证用户是否存在。这是正确的吗?
2)删除帐户后,我如何也删除其关联的用户。从帐户存储库?但这不仅仅是在用户存储库中重复代码吗?或者存储库可以相互引用和调用吗?
3)当用户被删除时,确定它是否与帐户相关联并在不重复代码的情况下将其删除的最佳方法是什么(可能类似于第二个问题)。
我在某处读到,如果逻辑跨越两个实体或聚合,请考虑使用服务。但我对此并不满意,因为是什么阻止了客户端(假设 API 将得到发展,并且用户将在未来使用其他演示文稿)绕过服务并简单地调用存储库?
更新1:
刚刚意识到这可能是一个相关的问题:我应该如何强制聚合根之间的关系和约束?
domain-driven-design - 多个聚合根之间的分页
我是 DDD 的新手,所以如果某些术语/理解有点偏离,请执行我。但请纠正我,任何建议表示赞赏。
假设我正在做一个社会工作委员会网站,并且我已经确定了我的总根源:候选人、工作和公司。非常不同的事物/上下文,因此每个都有自己的数据库表、存储库和服务。但现在我必须构建一个 Pinterest 风格的主页,其中的数据块显示候选人、工作或公司的数据。
现在棘手的部分是数据块必须在最后一次发生在它所代表的聚合上时进行排序(一家公司被点赞/评论,或者工作被更新等),并且分页再次以无限滚动的形式发生就像 Pinterest 一样。由于这些聚合是独立发生的,因此我无法知道任何特定页面上有多少聚合。(但如果我这样做了,比如说一个跟踪聚合上次更新时间的表,我别无选择,只能将其提升为另一个聚合根,并拥有自己的存储库?)
我将在哪里实现分页逻辑?我在某处读到,每个聚合根每个存储库应该有一个服务,所以我应该在控制器中排序和分页(顺便说一下,我正在使用 MVC)?还是应该有一个独立的应用程序服务来做这样的跨界工作?无论哪种情况,我都必须从数据库中获取所有聚合的所有实体?
这已经有太多问题了,但我基本上是在问:
- 是分页呈现、业务还是持久化逻辑?哪个水平层?
- 跨界代码应该在 DDD 中的哪个位置?哪个垂直堆栈?