EF Core与聚合根 – 有没有办法阻止将更改持久化到子实体?

huangapple go评论47阅读模式
英文:

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).

huangapple
  • 本文由 发表于 2023年5月25日 01:28:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76326043.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定