【问题标题】:Why collections of owned types generate an Id and how can I avoid that?为什么拥有类型的集合会生成一个 Id,我该如何避免这种情况?
【发布时间】:2020-12-30 19:36:02
【问题描述】:
正如微软所说的here:
拥有的实体本质上是拥有者的一部分,没有它就无法存在,它们在概念上类似于聚合
这意味着在 DDD 架构(领域驱动设计)中,我们可以使用拥有类型(或拥有类型的集合)作为聚合内的实体或值对象。另一方面,我们知道 DDD 中的 ValueObject 没有 Identity 值,因为它的结构和不变性。我想知道我是否决定使用 Owned 类型来实现值对象,如何强制它避免在创建表中创建 Id?
例如,如下图所示(Microsoft 提到了here),当我们使用拥有类型的集合时,EF 在表中创建了一个“Id”字段,这在地址值对象中没有意义!如何避免?它真的是一个正确的选择吗?
【问题讨论】:
标签:
entity-framework
.net-core
domain-driven-design
【解决方案1】:
该示例来自OwnsMany 场景,它清楚地说明它需要表中的 FK 将地址关联回其分销商es。加载实体时,地址记录如何关联回分发服务器?
如果 Distributor 只有 0-1 地址,那么您不需要 Address 上的 OwnerId,Address 的 Id 列将作为返回 Distributor 的 PK 和 FK。 EF 需要每个表上的“键”来唯一标识每一行。您可以通过映射复合键来避免“Id”列,本质上是:
public class Address
{
[Key, Column(0), ForeignKey("Owner")]
public int OwnerId { get; set; }
[Key, Column(1)]
public string Street { get; set; }
[Key, Column(2)]
public string City { get; set; }
public virtual Distributor Owner { get; set; }
}
地址表 IMO 的专用唯一且 DB 生成的 Id 列比字符串和 FK 的大型复合键更有意义。
就数据库而言,所有权与 HasOne / HasMany 在架构布局方式和关系规则方面相同。 OwnsMany 与 HasMany 的区别在于 EF 将如何允许您访问这些拥有的实体。您不能拥有DbSet<Address>,只能通过其分销商访问地址。它没有真正的目的,除了抓挠特定的设计模式之痒。 :)