ddd中的多对多关系

时间:2010-12-06 11:53:11

标签: domain-driven-design

我有两个实体Publisher和SocialAccount。 SocialAccount包含多个帐户 Twitter,Facebook等。

1个发布者可以附加到许多社交帐户,1个社交帐户包含多个发布者,此社交帐户还与另一个实体活动相关联。我的意思是两者都是独立的实体

创建发布商实例时,没有必要订阅社交帐户,它可以在以后订阅它。

我需要将发布商订阅到1个或多个社交帐户。我该怎么做

如何在发布商和社交帐户之间将m转换为m关系为1对多关系。我不确定,因为我在许多地方读到我们应该避免实体之间的M到M之间的关系。

2 个答案:

答案 0 :(得分:6)

答案 1 :(得分:6)

让我扩展唐的回答,因为我认为他正带领你走上正轨。

M-to-N关系是自然的,有用的,可以在DDD中处理。如果您需要M-to-N关系,则无需尝试将其转换为(或更可能是多个)M-to-1关系。 Udi Dahan's acticle给出了如何处理实体之间M-to-N关系的一个很好的例子。

首先,确定哪个实体应包含另一个实体的ID列表。 Udi使用职位发布(Job)和职位发布委员会(JobBoard)的例子。由于作业可以在没有作业板的情况下存在且作业板在没有作业的情况下不能存在,因此选择JobBoard作为聚合根并且将包含List<Job>。这可能看起来像是M-to-1关系,但是,由于每个Job可以在多个JobBoard的列表中,因此它实际上是M到N.

SocialAccountPublisher的情况下,我建议在C#中使用以下内容:

public class Publisher
{
    public int ID {get; private set;}

    private readonly IList<int> _AssignedSocialAccounts = new List<int>();
    public IEnumerable<int> AssignedSocialAccounts { get { return this._AssignedSocialAccounts; } }

    public Publisher(int ID) //Pass required fields to the constructor.
    {
        this.ID = ID;
    }

    public AssignSocialAccount(int SocialAccountID)
    {
        if(!this._AssignedSocialAccounts.Contains(SocialAccountID))
            this._AssignedSocialAccounts.Add(SocialAccountID);
    }
}

public class SocialAccount
{
    public int ID {get; private set;}

    public SocialAccount(int ID) //Pass required fields to the constructor.
    {
        this.ID = ID;
    }
}

(此示例使用类似于Jimmy Bogard's Wicked Domain Models的域封装。)

请注意,我选择Publisher作为聚合根,因为SocialAccount可以独立存在,但Publisher没有意义而没有SocialAccount

另请注意,我传递的是唯一ID,而不是对对象本身的引用。这是DDD中的常用方法,允许延迟加载相关实体,尽管权衡是您必须在需要访问实体时调用存储库来获取实体。

这种方法也意味着您没有将所有SocialAccount作为单个枚举。它们在各种Publisher之间分开。要获取所有SocialAccount的列表,需要单独查询。

相关问题