Many to Many, One to Many or Many to One

笑着哭i 提交于 2020-01-04 14:19:47

问题


I am trying to get my head around Doctrine 2 ORM relationships, I thought I had the hang of it but after reading a few symfony cookbook entries, I suspect I am actually a little confused.

I currently have a system where a template can contain multiple modules (including more than one of each type) and multiple templates can use the same module.

I thought that this would warrant a ManyToMany relationship and indeed looking at my table, it seems to work quite well.

However I realised as I was writing the database query that I needed the modules to load in a certain order, which means my join table needs to have a third 'order_by' column. I've read that a true join table is only ever two columns.

Hence the confusion. What should I set this up as in my entities?


回答1:


Like @Kris said - You'll go for One to Many towards middle entity. If you go for Many to Many instead then you won't have class file for middle table which is an issue in the most cases.

M-N assumption: ONE Student studies in MANY Courses and ONE COURSE can have MANY Students.

Both of the examples below give you this ERD in database but you want to go for ONE to MANY version.

MANY to MANY:

This will create StudentCourse entity in database but as you see no actual class file for you to deal with.

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:

This will create StudentCourse entity in database and as you see there is an actual class file for you to deal with when coding e.g. persist() etc.

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;
}

EDIT: onDelete="CASCADE" and cascade={"persist", "remove"} bits are not compulsory. They handle data redundancy. Is it bad to use redundant relationships?




回答2:


You would need a OneToMany/ManyToOne If you didn't need to save the order, it would be a manytomany, but since you do, that middle table now must be its own entity unfortunately. So you would need the following Entities

Template

with a OneToMany to

TemplateModules (probably a better name for this one)

With a ManyToOne to

Modules



来源:https://stackoverflow.com/questions/26565822/many-to-many-one-to-many-or-many-to-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!