问题
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