Doctrine Symfony中的条件关系

4
我需要在Symfony Entities中创建此数据库模式:
ClassA: - id - name - ...仅适用于类A的其他属性
ClassB: - id - name - ...仅适用于类B的其他属性
ClassC: - id - name - ...仅适用于类C的其他属性
Course: - id - name - type - class_id - class_type [A, B, C] - ...
我需要使用class_id将Course Entity与其他实体(ClassA、ClassB、ClassC)建立关系,使用id和class_type(A、B、C)进行映射。
Course不是一个类,类也不是课程。这里没有继承。在我的项目中,我使用这个概念(id和type映射不同的实体)。因此,我需要解决这个问题,并且像这个简单的例子一样。
我考虑在这里使用@ORM\DiscriminationMap:
/**
 * 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
{
 //...
}

或者类似这样的东西。

但我不想在ClassA、ClassB、ClassC实体中复制Course的属性,因为“extends”会将父实体的属性复制到子实体。

这不是关于继承的问题。我需要保持上述描述的数据库方案,而不添加其他实体的任何附加属性。

谢谢


那么,我理解你需要Class(A|B|C)Course之间的关系?这是两个不同的数据库表,对吗? - Petro Popelyshko
谢谢您的回复。是的,它们是4个实体(数据库表)。关系应该基于Course.class_type。 - Mohamed Aymen Karmous
1个回答

3
解决方案可能如下所示:
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;
        ....

    }

现在您将拥有一个单一的表格,它包含所有您的类别,并与课程之间建立了一对多的关联(这只是一个例子,取决于您的需求,您可以使用一对多或多对多)。

在DQL中,您可以通过INSTANCE OF找出所使用的类别。


1
这将添加一个额外的列“类型”,指定类别(A、B或C)。 - famas23
@Peter 谢谢您的回复。我按照您说的尝试了一下,这是一个我从未想过的好主意。但是我发现当我在ClassA、ClassB和ClassC类之前添加"@ORM\Table"和"@ORM\Entity"注释时,然后为每个类(A、B、C)添加其特定属性时,我遇到了两个问题:正如您所说,只有AbstractClass将保存为数据库表,第二个问题是类属性将被添加到Course表中。我只需要每个类在不同的表中具有其属性,而不是在一起。 - Mohamed Aymen Karmous
这个很好用,非常感谢。我增加了一些更改:在ClassA、ClassB和ClassC类之前添加注释"@ORM\Table"和"@ORM\Entity"。并将"@ORM\InheritanceType("SINGLE_TABLE")"替换为"@ORM\InheritanceType("JOINED")"以便在每个Class(A,B,C)的数据库表中有额外的属性。谢谢你,你救了我的项目。 - Mohamed Aymen Karmous
1
@MohamedAymenKarmous 不错! - Petro Popelyshko

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