如何将EF中的DDD值对象映射到不同的表?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将EF中的DDD值对象映射到不同的表?相关的知识,希望对你有一定的参考价值。

我有以下课程:

public class Customer
{
    public int CustomerId { get; private set; }
    public string Name { get; private set; }
    public Address MailingAddress { get; private set; }
    public Address BillingAddress { get; private set; }
    public Address InvoiceAddress { get; private set; }
}

public class Address //this is a Value Object, with no Id
{
    public int CityID { get; private set; }
    public string Address { get; private set; }
    public string ZipCode { get; private set; }

    public virtual City City { get; private set; }
}

public class City
{
    public int CityID { get; private set; }
    public string Name { get; private set; }
}

假设域驱动设计中的值对象没有标识,我如何使用EF Code-First将上述场景映射到不同的表中?这种方法可行吗?

我真的不喜欢在同一个客户表上拥有不同地址的所有字段,但同时,我不想让我的域变脏对象Value Objects的身份。

答案

我同意你的看法,价值对象需要与实体对象不同的处理方式。毕竟,当两个人拥有相同的DOB时,我们不会存储这些人所指的一个日期对象。

但是,在我看来,映射到商店模型的类模型是not a domain model。如果你很幸运,它可能会接近,但它的主要职责是充当数据访问层。这些数据恰好与Codd这个词有关。

您要存储在关系数据库中的所有内容都必须具有标识。您的地址相同。由于您不希望它们成为Customer表的一部分(作为复合实体),因此您没有其他选择,只能将它们与身份存储在一个单独的表中。没那么糟糕。

另一答案

虽然在使用DDD时使用关系数据库并不是一个好主意,因为它在数据库中是冗余的,但是您可以通过将值对象指定为表中的主键来将DDD的值对象映射到单独的表中(没有其他选择)。

 public class AddressMapping : EntityTypeConfiguration<Address>
    {
        public AddressMapping()
        {
            HasKey(t => t.Address);
            Property(t => t.ZipCode); 
            // balh blah
        }
    }

value对象应该是不可变的,因此您应该将属性设置为模型中的私有集。注意:sql server不会让你在主键中持有更多15000个字符,因为你的主键是地址。所以你的值对象必须足够短,不仅仅是对主键的sql server限制。

以上是关于如何将EF中的DDD值对象映射到不同的表?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用流利的 api 在 EF6 中映射值对象标识?

EF- '' 和 '' 都映射到表 ''。层次结构中没有鉴别器的所有实体类型必须映射到不同的表

EF Core 如何实现对值对象更改的审计日志

如何将领域类与EF代码第一层分离并在项目中实现DDD

如何使用 hibernate/jpa 注释将一个类映射到不同的表

我如何设计具有受保护/私有成员 DDD 样式的 EF5 代码优先实体