简体   繁体   中英

Conditional relations with doctrine Symfony

I have need to create this database scheme in Symfony Entities :

ClassA:

  • id
  • name
  • ... some other attributes only for class A

ClassB:

  • id
  • name
  • ... some other attributes only for class B

ClassC:

  • id
  • name
  • ... some other attributes only for class C

Course:

  • id
  • name
  • type
  • class_id
  • class_type [A, B, C]
  • ...

I need to create relations between Course Entity (using the class_id) with the other entities (ClassA, ClassB, ClassC) (using the id) and using the class_type (A, B, C).

A Course is not a class and a class is not a course. There is no inheritance here. In my project I'm using this concept (id and type to map different entities). So I need to solve this problem with a simple example like this one

I thought about using @ORM\\DiscriminationMap here:

/**
 * Course
 *
 * @ORM\Table(name="Course")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="course_type", type="string")
 * @ORM\DiscriminatorMap({"A" = "ClassA", "B" = "ClassB", "C" = "ClassC"})
 */
abstract class Course
{
 //...
}

class ClassA extends Course
{
 //...
}

class ClassB extends Course
{
 //...
}

class ClassC extends Course
{
 //...
}

Or something like this.

But I don't want to copy the Course's attributes in the ClassA, ClassB, ClassC entities because "extends" will copy the parent entity's attributes to the child.

It's not about inheritence. I need to keep the database scheme described above without adding any additional attributes from the other entities.

Thank you

Solution might be next:

use Doctrine\ORM\Mapping as ORM;
    /**
     * @ORM\Entity
     * @ORM\Table(name="class")
     * @ORM\InheritanceType("JOINED")
     * @ORM\DiscriminatorColumn(name="type", type="string", length=20)
     * @ORM\MappedSuperclass
     * @ORM\DiscriminatorMap({
     *     "class_a" = "ClassA",
     *     "class_b" = "ClassB",
     *     "class_c" = "ClassC"
     * })
     */
    abstract class AbstractClass
    {
       ... common fields
        /**
         * @var PersistentCollection
         *
         * @ORM\OneToMany(targetEntity="Course", cascade={"persist"}, mappedBy="course")
         */
        protected $courses;

    }
   /**
    * @Entity
    * @ORM\Table(name="class_a")
    */
    class ClassA extends AbstractClass
    {
     //...
    }
   /**
    * @Entity
    * @ORM\Table(name="class_b")
    */
    class ClassB extends AbstractClass
    {
     //...
    }
   /**
    * @Entity
    * @ORM\Table(name="class_c")
    */
    class ClassC extends AbstractClass
    {
     //...
    }

   /**
    * @Entity
    * @ORM\Table(name="course")
    */
    class Course
    {

        /**
         * @var AbstractClass
         * @ORM\ManyToOne(targetEntity="AbstractClass", inversedBy="course")
         * @ORM\JoinColumn(onDelete="CASCADE")
         */
        private $course;
        ....

    }

So now you'll have single table for all your classes with one to many relation to course (this is just an example, you could use one to many or many to many, depends on your needs).

Within DQL you can find out which class is used with INSTANCE OF .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM