如何建模多个多对象之间的关系

时间:2014-11-27 15:20:10

标签: c# many-to-many domain-driven-design relationship

我正在开发一个使用iBatis作为ORM的旧c#应用程序。我在建模两个我必须添加到域中的新实体时遇到了一些问题。

我有3个旧实体:ProcessSocietyActivity

现在我必须添加:

  • 过程与社会之间的多对多关系
  • 活动与上述M2M关系之间的多对多关系

这两种关系都有一些属性,我必须从两个方向访问它们: 我需要知道:

  • 社会的全过程
  • 所有参与过程的社会
  • 在社会过程中完成的所有活动
  • 活动中所有社会的所有过程

正如我项目中所有其他M2M一样,我将第一个关系映射为3个对象:

  • BaseLinkProcessSociety包含关系属性(与社会和负责人的过程相关性)
  • LinkProcessSociety通过添加社会对象来扩展基础对象
  • LinkSocietyProcess通过添加Process对象来扩展基础对象

以这种方式在我的Process对象中我有LinkProcessSociety的列表,而在Society对象中我有LinkSocietyProcess对象的列表

现在问题是:我如何映射第二个M2M关系?我没有一个映射整个ProcessSociety的对象。我必须创建它吗?我不太喜欢这个想法

还有其他更好的建模解决方案吗?

编辑@Sebastian Oliveri回答

在M2M对象中我必须添加一些属性,因此它不能通用,

使用您的ProcessOfSociety对象:

class ProcessOfSociety {
    var processId;
    var societyId;
    Person personInCharge;
    int relevance;
} 

但我的问题是:如何将此对象映射为Process对象中的属性?

我希望有这样的东西

class Process {
    var processId;
    var processDescription;
    IList<ProcessOfSociety> SocietyInvolvedList; 
}

使用此协议:

process.SocietyInvolvedList[1].Society.societyDescription

甚至

class Society{
    var societyId;
    var societyDescription;
    IList<ProcessOfSociety> FolowedProcesses; 
}

使用此协议:

society.FolowedProcesses[1].Process.processDescription

因此我无法在ProcessOfSociety

中拥有ID属性

1 个答案:

答案 0 :(得分:0)

在这种场景中,您需要忘记在经典关系方法中思考并将关系作为一流的概念。 为了创建一个关系作为第一类概念,您首先需要创建这两个彼此相关的对象中的一个。在这种情况下,您需要一个社会,所以在您的应用程序的某个地方,您将拥有:

society = new Society("my society");
societyRepository.add(society);

在您申请的其他地方,您将获得“服务”,这将创建一个与社会相关的流程:

society = societyRepository.get(societyId);
process = processRepository.get(processId);
processOfSociety = society.register(process);
processesOfSocietyRepository.add(processOfSociety);

ProcessOfSociety课程模拟社会与过程之间的关系。

class ProcessOfSociety {

    var processId;
    var societyId;

    ...

}

当然,您需要一个流程来关联。流程本身就是一个聚合处理AR,因此对上述步骤进行建模的前提条件是首先创建一个流程。

您需要按照上述相同的概念对Activity Aggregate执行相同的操作。请记住,扮演关系角色的这些类包含聚合的标识符,而不是促进断开连接模型的聚合。

注意ProcessOfSociety类对关系进行建模。您需要考虑这些对象的协议是什么。如果它只是getProcessId()和getSocietyId(),那么你可以考虑一个更好的抽象,可以重用于其他用例。如果你只想对两个对象之间的关系进行建模,那么对这个答案的回答就在你为这篇文章写的标题中:

class ManyToManyRelationship {

    var left;
    var right;

}

许多次在DDD(OOP)中,答案是在域语义中:)

更新回答你的问题:

您不需要协会持有ProcessOfSociety列表。两者都是具有全局标识的聚合,因此它们拥有自己的存储库,因此如果要查找社团的所有进程,则需要使用存储库:

List processesOfSociety = processesOfSocietyRepository.find(societyId)

请记住,聚合通常是对价值对象的“微小”破坏,它们可能在其边界内有一个值对象列表,但如果你使聚合持有对另一个聚合的引用,那么这就是气味设计。在您的方案中,您将汇总一个其他聚合列表。

希望它有所帮助。