nhibernate - DDD 聚合根子关系 NHibernate 映射

标签 nhibernate domain-driven-design

我试图遵循聚合设计原则,并提出了一个我需要帮助的情况。我的聚合根是一个 Customer 对象。 Customer 对象具有 Address 对象的子集合和 Contact 对象的子集合。

Contact 可以引用 Customer 聚合下的 AddressCustomer 对象具有唯一的 IDAddressContact 对象具有本地 ID,因此主键在数据库中将是 CustomerIdAddressId

以下是简化的类:

public class Customer : AggregateRoot {
    public virtual int CustomerId { get; protected set; }
    public virtual IList<Address> Addresses { get; protected set; }
    public virtual IList<Contact> Contacts { get; protected set; }
}
public class Address : Entity {
    public Address(Customer customer, int addressId) {
        this.Customer = customer;
        this.AddressId = addressId;
    }

    public virtual Customer Customer { get; protected set; }
    public virtual int AddressId { get; protected set; }
}
public class Contact : Entity {
    public Contact(Customer customer, int contactId) {
        this.Customer = customer;
        this.ContactId = contactId;
    }

    public virtual Customer Customer { get; protected set; }
    public virtual int ContactId { get; protected set; }
    public virtual Address Address { get; set; }
}

数据库具有如下表:

客户

CustomerId int identity PK

地址

CustomerId int not null PK,FK
AddressId int not null PK

联系方式

CustomerId int not null PK,FK
ContactId int not null PK
AddressId int null FK

当我尝试使用 Fluent NHibernate 映射我的实体时,我的问题就出现了。由于 Address 对象具有 CustomerIdAddressId 的复合键,NHibernate 不会重用列​​ CustomerId联系表。当我尝试保存聚合时,出现异常,提示值多于参数。发生这种情况是因为 Address 对象具有复合 ID,并且不与 Contact 对象共享 CustomerId 列。

解决此问题的唯一方法是在 Contact 表中添加 AddressCustomerId 列,但现在我有一个重复的列作为 CustomerId AddressCustomerId 是相同的值。无论如何,有这种行为吗?

最佳答案

如果地址和联系人都没有客户聚合之外的身份,则应将它们映射为组件集合。另外,客户-地址和客户-联系人关系是否需要是双向的?是否需要addressId和contactId?如果模型被简化,这将起作用:

public class Customer
{
    public virtual int CustomerId { get; protected set; }
    public virtual IList<Address> Addresses { get; protected set; }
    public virtual IList<Contact> Contacts { get; protected set; }
}

public class Address
{
    public string Street1 { get; private set; }
    public string Street2 { get; private set; }
    public string City { get; private set; }
    public string Region { get; private set; }
}

public class Contact
{
    public string Name { get; private set; }
    public string Email { get; private set; }
    public virtual Address Address { get; set; }
}

public class CustomerMap : FluentNHibernate.Mapping.ClassMap<Customer>
{
    public CustomerMap()
    {
        Table("Customers");
        Id(x => x.CustomerId);
        HasMany(x => x.Addresses)
            .Table("CustomerAddresses")
            .KeyColumn("CustomerId")
            .Component(m =>
            {
                m.Map(x => x.Street1);
                m.Map(x => x.Street1);
                m.Map(x => x.City);
            });
        HasMany(x => x.Contacts)
            .Table("CustomerContacts")
            .KeyColumn("CustomerId")
            .Component(m =>
            {
                m.Map(x => x.Name);
                m.Map(x => x.Email);
                m.Component(x => x.Address, ma =>
                {
                    ma.Map(x => x.Street1);
                });
            });
    }
}

在映射中,地址和联系人集合被映射为组件。这意味着它们不需要有自己的身份,因此不需要单独的映射类。然而,在此模型中,联系人的地址将与联系人数据本身存储在同一行中,我认为这是一个很好的模型(而不是更规范化的模型)。

关于nhibernate - DDD 聚合根子关系 NHibernate 映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11783414/

相关文章:

domain-driven-design - 分解微服务 : Business capability vs Domain

design-patterns - 单一职责原则的范围是什么?它如何与 DRY 一起工作?

domain-driven-design - 域内的域服务或方法

c# - NHibernate session 管理?

c# - NHibernate 映射异常。 : NHibernateTesting. 帐户没有持久性

Nhibernate show_sql=false 不工作

asp.net - DDD中有没有关于共享值对象的概念

java - 如何使用Spring Data Jpa将一个领域实体对象写入多个数据库表?

c# - 自动映射和 Fluent NHibernate

c# - IList.Cast<typeof(T)>() 返回错误,语法看起来没问题