【问题标题】:How to model relationship between multiple many to many object如何建模多个多对多对象之间的关系
【发布时间】:2014-11-27 15:20:10
【问题描述】:

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

我涉及 3 个旧实体:ProcessSocietyActivity

现在我必须添加:

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

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

  • 一个社会的所有过程
  • 一个过程中涉及的所有社会
  • 在社会进程中完成的所有活动
  • 在一项活动中分析所有社会的所有过程

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

  • BaseLinkProcessSociety 包含关系属性(与社会和负责人的过程相关性)
  • LinkProcessSociety 通过添加 Society 对象扩展基础对象
  • 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 属性

【问题讨论】:

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


    【解决方案1】:

    在这种情况下,您需要忘记以经典的关系方法进行思考,并将关系视为一流的概念。 为了将关系创建为第一类概念,您首先需要创建将相互关联的这两个对象中的一个。在这种情况下,您需要一个 Society,因此在您的应用程序的某处您将拥有:

    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) 中,答案在域语义中:)

    更新回答你的问题:

    您不需要 Society 来保存 ProcessOfSociety 的列表。两者都是具有全局身份的聚合体,因此它们有自己的存储库,因此如果您想查找某个 Society 的所有进程,则需要使用存储库:

    List processesOfSociety = processesOfSocietyRepository.find(societyId)
    

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

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2021-08-26
      • 1970-01-01
      • 2017-08-25
      • 2018-06-20
      • 2020-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多