在连接表中使用额外列进行多对多映射

时间:2009-01-23 06:14:35

标签: orm nhibernate-mapping domain-driven-design

以下是我希望拥有的域名:

public class Person
{
    public int Id { get; set; }
    public IList<AcquiredCertificate> AcquiredCertificates { get; set; }
}

public class AcquiredCertificate
{
    public Person Acquirer { get; set; }
    public Certificate Certificate { get; set; }
    public DateTime DateAcquired;
}

public class Certificate
{
    public int Id { get; set; }     
}

这就是我的架构:

CREATE TABLE People (
    PersonId INT PRIMARY KEY
);

CREATE TABLE Certificates (
    CertificateId INT PRIMARY KEY
);

CREATE TABLE CertificatesAcquiredByPeople (
    PersonId INT,
    CertificatedId INT,
    DateAcquired DATETIME
);

这是一个人为的架构和域名,但它与我正在使用的东西几乎相同。我目前通过编写第三个域实体来代表CertificatesAcquiredByPeople表来工作,但这对我来说真的很奇怪。

我如何使用NHibernate进行映射?我相信hbm文件中的组件标签应该做我想要的,但我无法弄明白。

我的域名是不是因为我的证书类上有DateAcquired属性?这个日期实际上只是拥有证书的人的关注点。

[编辑]

我现在改变了域模型,以反映需要一个新实体。现在对于映射,我需要3个(对于每个实体)映射,还是可以使用2(对于Person和Certificate)?

5 个答案:

答案 0 :(得分:5)

根据设计,如果除了在中间(中间)表中表示的具有多对多关系的FK对之外,NHibernate仅支持隐式的多对多映射。

不久前,Billy McCafferty在博客中写到了这个确切的“问题”(自BY DESIGN以来并不是真正的问题)......

http://devlicio.us/blogs/billy_mccafferty/archive/2008/07/11/when-to-use-many-to-one-s-vs-many-to-many-with-nhibernate.aspx

答案 1 :(得分:1)

如果您想获得DateTime值,我认为您需要3。

答案 2 :(得分:0)

您的实施完全正确。您的连接表包括两个关键字段(为表创建复合主键),而datetime字段对此是多余的。它实际上是连接表上的额外属性,因此您需要一个实体。

在UML类图上,它也会在连接中显示为属性。

答案 3 :(得分:0)

我会将CertificatesAcquiredByPeople重命名为 像CertificatesAcquiredEvent(它意味着有多个密钥和日期时间)

我同意就NHibernate而言,它必须是一个单独的实体。

答案 4 :(得分:0)

Re:你更新的Q,你将需要三个映射,一个用于现在参与这对一对多关系的三个实体中的每一个。