英文:
EF Core vs Aggregate Root - Is there a way to prevent persisting changes to child entities?
问题
I'll provide translations for the non-code parts of your text:
"因为所有的更改都需要通过聚合根进行,所以我在Order
中添加了一个IReadOnlyList<LineItem> LineItems
导航属性,由private readonly List<LineItem> lineItems
字段支持。所以现在我们不能只是order.LineItems.Add()
,而是必须使用聚合根上的适当的AddLineItem
方法来添加行项目。
但是,为了能够在使用EF Core从数据库中获取的Order
实体上使用AddLineItem
,我需要在查询中使用Include(o => o.LineItems)
,否则LineItems
将为null
,并且在尝试添加时会引发异常。那么如何阻止我从只读列表中获取LineItem并对其进行更改,然后使用DbContext.SaveChanges()
进行持久化呢?
是否有一种方法可以防止这种情况发生?"
英文:
I'll use the common example of an Order
aggregate root which has a collection of LineItems
.
Because all changes need to go through the aggregate root, I add a IReadOnlyList<LineItem> LineItems
navigation property to the Order
, backed by a private readonly List<LineItem> lineItems
field. So now we can't just do order.LineItems.Add()
, but instead we have to use an appropriate AddLineItem
method on the aggregate root to add the line item.
But, in order to be able to use the AddLineItem
on an Order
entity fetched from the database using EF Core, I need to use Include(o => o.LineItems)
in my query, otherwise LineItems
would be null
, and I'd get an exception when trying to add to it. So what's stopping me from getting a LineItem from the read-only list and doing changes on it, and then persisting them using DbContext.SaveChanges()
?
Is there a way to prevent this?
答案1
得分: 1
你应该将LineItem
上的setter方法设置为internal
。这样,唯一能够更改它们的实体就是同一程序集中的那些,例如Order
。
所有更改LineItem
属性的请求都应该通过Order
进行路由,然后Order
可以强制执行不变性并使用内部setter来更新LineItem
(甚至可以使用LineItem
上的内部方法,该方法负责使用私有setter来更新属性)。
英文:
You should make your setters internal on LineItem
. Then the only entities that can change them are those in the same assembly, e.g. the Order
.
All requests to change properties of the LineItem should be routed through the Order, which can then enforce invariants and use internal setters to update the LineItem (or even use internal methods on the LineItem, which takes care of updating properties with private setters).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论