如何编写多对多关系的代码?

4

我对连接数据库和面向对象编程感到困惑。

例如,想象一个教师的成绩单应用程序,其中UI显示表格行中的学生和列中的作业。底层数据库可能包括多对多关系:一个学生有许多作业,一个作业有许多学生。

那么底层代码是如何工作的呢?你是否有一个Student类,其中有一个变量引用了一个作业列表?或者一个Assignment类,其中有一个变量引用了一个学生列表?还是两个都有?...你是否有某种StudentAssignment类,链接Student和Assignment的实例?(如果有,这是否意味着一个有50名学生和10项作业的班级同时在内存中有500个StudentAssignment对象,50个Student对象和10个Assignment对象?!)...然后这些不同的类主要由(例如)与底层数据库一起工作的SQL语句组成吗?

我知道这里有很多问题,但它们都有点相关...编写多对多关系的通常接受策略是什么?

p.s. 为了避免你认为我很懒,我确实查看了其他问题,比如如何在代码中建模多对多关系?用属性建模多对多关系

2个回答

3
在数据库中,你需要一个学生表、一个作业表和一个StudentAssignment的交叉表。这个OOP的表示可以是每个学生都有他们作业的集合。如果你需要查看哪些学生有特定的作业,那么请在作业对象上填充这些信息。或者,你也可以检查每个学生是否有特定的作业。这取决于你。
数据库在数据表示和访问方面存在限制,而这些限制在OOP语言中不一定存在。
但是,你绝对不需要一个StudentAssignment对象。那个表达的是关系,而不是实体。
如果你需要从作业到拥有该作业的学生以及从学生到他们所有作业的路径,那么你需要50个学生对象和10个作业对象。当你创建这些对象时,你需要在每个对象上填充与之关联的对象的集合(一个学生将有一个作业列表,反之亦然)。
假设你这样做了:
为所有学生创建对象(这返回50条记录),并将它们的作业集合设置为空列表。
SELECT
    StudentName,
    ID
FROM
    Student

创建所有作业的对象(这将返回10个记录),并将它们的学生集合设置为空列表。
SELECT
    AssignmentName,
    ID
FROM
    Assignment

假设您使用以下方式查询所有数据:(假设每个学生都有每个作业,这将返回500条记录)
SELECT
    Student.ID [StudentID],
    Assignment.ID [AssignmentID]
FROM 
    Student
    INNER JOIN StudentAssignment ON Student.ID = StudentAssignment.StudentID
    INNER JOIN Assignment ON Assignment.ID = StudentAssignment.AssignmentID

您需要遍历这500个记录,为每个关系添加对应的对象。最终,您仍然只有那60个对象(50 + 10),但它们的关系是由每个对象所拥有的Assignments或Students的集合定义的。


那么,这是否意味着(在上述例子中),程序需要创建50个学生对象、10个作业对象,并在显示和/或操作学生分配信息时调用StudentAssignment交集表? - Al C

1

你的困惑是可以理解的,将SQL模式转换为OO通常会令人困惑,因为它们是不同的范例。

如果你考虑OO提供了一种抽象底层实现的方式,那么你就会更清晰地找到答案。为每个SQL表创建一个对象在清晰度或更好的抽象层面方面并没有什么帮助。

你是否有一个学生类,其中包含引用作业列表的变量?或者一个作业类,其中包含引用学生列表的变量?两者都有吗?

我可能会根据数据访问模式来做这两个,具体情况而定。

你是否有某种StudentAssignment类链接Student和Assignment的实例?

不需要,将此实现细节隐藏在你的StudentAssignment类中即可。

那么这些不同的类主要由(例如)使用底层数据库的SQL语句组成吗?

它们可以,并且在实际生活中通常会这样做,但你也可以让它们调用其他实际访问数据的类,例如使用存储库模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接