多对多,一对多或多对一

时间:2014-10-25 18:34:16

标签: symfony orm doctrine-orm entities

我试图了解Doctrine 2 ORM关系,我认为我已经掌握了它,但在阅读了一些symfony食谱条目后,我怀疑我实际上有点困惑。

我目前有一个系统,其中模板可以包含多个模块(包括每种类型的多个模块),并且多个模板可以使用相同的模块。

我认为这将保证ManyToMany的关系,并且确实在看我的桌子,它似乎工作得很好。

但是我意识到,当我编写数据库查询时,我需要按特定顺序加载模块,这意味着我的连接表需要有第三个'order_by'列。我已经读过真正的连接表只有两列。

因此混乱。我应该如何在我的实体中设置它?

2 个答案:

答案 0 :(得分:4)

就像@Kris所说的那样 - 你会选择一对多的中间实体。如果您选择“多对多”,那么您将不会拥有中间表的类文件,这在大多数情况下都是一个问题。

M-N假设:一个学生在多个课程学习,一个课程可以有很多学生。

以下两个示例都为您提供了数据库中的ERD,但您希望获得一个到多个版本。

enter image description here

MANY to MANY:

这将在数据库中创建StudentCourse实体,但是您没有看到实际的类文件供您处理。

class Student
{
    protected $id;
    protected $name;

    /**
     * @ORM\ManyToMany(targetEntity="Course")
     * @ORM\JoinTable(
     * name="StudentCourse",
     * joinColumns={@ORM\JoinColumn(name="studentId", referencedColumnName="id")},
     * inverseJoinColumns={@ORM\JoinColumn(name="courseId", referencedColumnName="id")}
     * )
     */
    private $course;
}

class Course
{
    protected $id;
    protected $name;
}

ONE TO MANY:

这将在数据库中创建StudentCourse实体,如您所见,有一个实际的类文件供您在编码时处理,例如persist()等。

class Student
{
    protected $id;
    protected $name;

    /**
     * @ORM\OneToMany(targetEntity="StudentCourse", mappedBy="studentMap",
     * cascade={"persist", "remove"})
     */
    protected $studentInverse;
}

class StudentCourse
{
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Course", inversedBy="courseInverse")
     * @ORM\JoinColumn(name="course", referencedColumnName="id",
     * nullable=false, onDelete="CASCADE")
     */
    protected $courseMap;

    /**
     * @ORM\ManyToOne(targetEntity="Student", inversedBy="studentInverse")
     * @ORM\JoinColumn(name="student", referencedColumnName="id",
     * nullable=false, onDelete="CASCADE")
     */
    protected $studentMap;
}

class Course
{
    protected $id;
    protected $name;

    /**
     * @ORM\OneToMany(targetEntity="StudentCourse", mappedBy="courseMap",
     * cascade={"persist", "remove"})
     */
    protected $courseInverse;
}

修改 onDelete="CASCADE"cascade={"persist", "remove"}位不是强制性的。它们处理数据冗余。 Is it bad to use redundant relationships?

答案 1 :(得分:1)

你需要一个OneToMany / ManyToOne 如果您不需要保存订单,那将是一个很多人,但是既然如此,那么中间表现在必须是它自己的实体。 所以你需要以下实体

模板

使用OneToMany

TemplateModules(可能是这个名称的更好名称)

使用ManyToOne

模块