【问题标题】:How should I handle persistence for referenced entities?我应该如何处理引用实体的持久性?
【发布时间】:2015-03-02 17:19:09
【问题描述】:

我正在使用实体框架和 DDD。

如果我有两个实体之间的引用,我应该如何处理持久性?更新会级联吗?

假设雇主直接参考了他们的经理。

如果我更改 Employee.Manager.Name 并保存 Employee,经理的姓名是否会更改?

【问题讨论】:

  • 您不应在单个事务中修改多个聚合根。倾向于通过身份引用而不是对象引用:这将有助于避免此类错误。

标签: c# entity-framework repository domain-driven-design


【解决方案1】:

从 DDD 的角度来看,从 EmployeeManager 的任何链接都应该仅通过引用 id 来实现(假设 Managers 不是 Employee 聚合根的一部分并且 Manager本身就是一个聚合根)。

本质上,您的属性Employee.ManagerId 应该返回一个 ID,允许您检索该 EmployeeManager

这将与您使用 Entity Framework 开箱即用的许多“优点”背道而驰,但这对于 DDD 来说很常见。建议围绕业务域而不是数据库实现来设计域模型。

就我个人而言,我发现在我练习 DDD 时使用 EF 实体作为我的域模型并不适合。诸如延迟加载导航属性之类的事情与良好的 DDD 实践相矛盾。这些天来,我倾向于在自己的项目中使用文档数据库,但是当我必须使用 SQL 时,我将 EF 实体限制在我的持久层,并将我的存储库编码为从我的域模型返回非 EF 实体。

【讨论】:

  • 优秀的答案。 EF 非常适合 CRUD,但在持久化领域驱动的设计实体时需要谨慎使用
  • @AdrianThompsonPhillips 我倾向于同意如果这两个实体都是聚合根,OP 没有指定。关于 EF 实体/域实体,我也会比你更细致入微。 “大多数练习 DDD 的人”在这里似乎有点笼统。
  • @AdrianThompsonPhillips 那么优化性能呢?我的意思是,在这个其他答案中:stackoverflow.com/a/27502014/967124@marianoc84 谈到了一个可能的 ValueObject,在这个问题的情况下可能是 EmployeeManager,它将包含 ManagerIdManagername (假设我们只有在获取员工列表时才需要这个属性。这样,我们就不需要再根据ManagerId获取Manager的名称了。顺便说一句,我不知道是不是这样是一个很好的设计决策,因为有多个缺点。意见?
  • @marianoc84s 的回答有点不清楚,如果他们提倡一个 AR(聚合根)持有对另一个 AR 的对象引用,那么这听起来不是很 DDD。但是,如果他们通过 id 引用引用,那很好。就个人而言,如果获得经理的额外打击是如此昂贵,我会使用 AppFabric、Memcached、Redis 等以某种方式对其进行数据缓存。我无法想到何时需要同时加载许多员工和他们的经理。如果出于报告目的提出此要求,那么我将从单独的报告数据库中获取数据。
  • 我明白你的意思@AdrianThompsonPhillips。顺便说一句,我试图用EmployeeManager 举一个更复杂问题的例子。例如:假设您有一个由Employee 创建的Order 列表,这个Employee 居住的City,他/她在公司关联的Role 等等。您最终将通过标识符的值对象引用所有这些数据,并在EmployeesList 域服务中执行所有“模拟连接”。尽管可以缓存它,但这听起来很奇怪。我理解的好吗?谢谢!
【解决方案2】:

假设您的应用程序使用一个 DbContext:

是的,它也会保存引用的实体。

在您设置 Manager 名称的那一刻,它将加载 Manager 引用并跟踪它。当您通过调用DbContext.SaveChanges 保存更改时,它将提交对DbContext 正在跟踪的对象所做的所有更改。

避免这种行为的唯一选择是使用多个DbContext 实例,但这会引发许多其他问题(例如:它们不知道彼此的变化)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 2019-09-16
    • 2012-01-14
    相关资源
    最近更新 更多