отношения многие ко многим в DDD - PullRequest
7 голосов
/ 06 декабря 2010

У меня есть две сущности Publisher и SocialAccount. SocialAccount содержит несколько учетных записей, таких как Twitter, Facebook и т. Д.

1 издатель может присоединиться ко многим социальным учетным записям, а 1 социальная учетная запись содержит несколько издателей, эта социальная учетная запись также связана с другой кампанией. Я имею в виду, что оба являются независимой организацией

При создании экземпляра издателя необязательно, чтобы он подписывался на социальную учетную запись, он может подписаться на нее на более позднем этапе.

Мне нужно подписать издателя на 1 или несколько социальных аккаунтов. как мне это сделать

как я могу преобразовать отношения m в m в отношения 1 ко многим, между издателем и социальным аккаунтом. Я не уверен, потому что я читал во многих местах, что мы должны избегать отношений М-М между сущностями.

Ответы [ 2 ]

6 голосов
/ 09 августа 2014

Позвольте мне подробнее остановиться на ответе Дона, так как я думаю, что он ведет вас по правильному пути.

Отношения M-to-N являются естественными, полезными и могут обрабатываться в DDD. Если вам требуется отношение M-to-N, вам не нужно пытаться преобразовать его в (или, что более вероятно, в несколько) отношение M-to-1. В статье Уди Дахана приведен хороший пример того, как обрабатывать отношения M-to-N между сущностями.

Сначала определите, какой объект должен содержать список идентификаторов другого. Уди использует пример объявлений о работе (Job) и досок объявлений о работе (JobBoard). Поскольку задание может существовать без доски заданий, а задание не может существовать без заданий, JobBoard выбран в качестве совокупного корня и будет содержать List<Job>. Это может показаться отношением M-to-1, но, поскольку каждый Job может быть в списке для нескольких JobBoard s, это действительно M-to-N.

В вашем случае SocialAccount и Publisher, я рекомендую что-то подобное в 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;
    }
}

(В этом примере используется инкапсуляция домена, аналогичная Модели Злого Домена Джимми Богарда .)

Обратите внимание, что я выбрал Publisher в качестве совокупного корня, поскольку SocialAccount может существовать сам по себе, но Publisher не имеет смысла без существования SocialAccount.

Также обратите внимание, что я передаю уникальные идентификаторы, а не ссылки на сами объекты. Это распространенный подход в DDD и позволяет выполнять отложенную загрузку связанных сущностей, хотя компромисс заключается в том, что вы должны вызывать хранилище для получения сущностей, когда вы хотите получить к ним доступ.

Этот подход также означает, что у вас нет всех SocialAccount с одним перечислением. Они разделены между различными Publisher с. Для получения списка всех SocialAccount потребуется отдельный запрос.

6 голосов
/ 31 января 2011

Уди Дахан имеет пример этого и как его избежать: http://www.udidahan.com/2009/01/24/ddd-many-to-many-object-relational-mapping/

...