使用 EF 的 DDD:值对象的集合

DDD with EF: Collection of Value objects

在一个研究领域中,一个 Car 可能有很多 Tire,根据 DDD 概念,Car 是一个 aggregate rootTire 是一个Value Object。 '

考虑以下模型:

class Car
{
   public int Id {get;set;}
   public virtual ICollection<Tire> Tires {get;set;}
}

[ComplexType]
class Tier
{
   public string Manufacturer {get;set;}
   public int Diameter {get;set;}
}

恐怕 EF 6.0 + 无法实现此模型。我对吗?有什么方法可以实现值对象集合?

这是规范化持久性(包括您通过 EF 访问的 SQL 服务器)的常见问题。 Entity framework 虽然不允许您拥有受保护的密钥,但让事情变得更加困难。

一种方法是拥有一个 Tires table,它有一个 id,它将构成与 car 的外键关系的一部分。然而,唯一键的想法违反了值对象不应该依赖于 id 而应该按值进行比较的事实。勤奋,超越等于,只按价值比较将允许您使用此解决方案;只要两个轮胎匹配时相等比较 return 为真,实际对象是否不同并不重要。它并不漂亮,我同意,但对于 EF,它似乎是唯一的解决方案。如果我错了,请有人纠正我。如果你走这条路,请记住以删除 Id 的方式将你的域数据映射到你的 DTO。这样你就可以保持轮胎有一个独立的 id 的事实。

另一种解决方案是在发送到 SQL 数据库之前使用 Json 对轮胎进行序列化(然后在读取时反序列化),但这不是我个人的建议,如果你需要查询轮胎的信息(比如给我所有使用这种轮胎的车)。

PS:Vaughn Vernon 在本书中针对 Java 讨论了 Hibernate 的这个特殊问题:http://www.amazon.co.uk/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577 请阅读,它将解决您可能遇到的许多问题或疑问关于这个问题。

复杂类型,根据 MSDN 文档,不能参与关联并且不能包含导航属性所以这不是正确的方法。 对于 EF,唯一的方法是拥有 2 tables(在轮胎上有一个 Id table)。您还可以隐藏轮胎的 Id table,您可以在 Cars table 的外键上插入唯一索引但是当您检查两个轮胎是否相等时,您需要检查两个属性是否相等.