与学说 Symfony 的条件关系

Posted

技术标签:

【中文标题】与学说 Symfony 的条件关系【英文标题】:Conditional relations with doctrine Symfony 【发布时间】:2017-12-05 09:12:47 【问题描述】:

我需要在 Symfony 实体中创建这个数据库方案:

A 类:

身份证 姓名 ...其他一些属性仅适用于 A 类

B 类:

身份证 姓名 ...其他一些属性仅适用于 B 类

C类:

身份证 姓名 ...其他一些属性仅适用于 C 类

课程:

身份证 姓名 类型 class_id class_type [A, B, C] ...

我需要在课程实体(使用 class_id)与其他实体(ClassA、ClassB、ClassC)(使用 id)和使用 class_type(A、B、C)之间创建关系。

课程不是课程,课程也不是课程。这里没有继承。在我的项目中,我使用了这个概念(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 的属性,因为“扩展”会将父实体的属性复制到子实体。

这与继承无关。我需要保留上述数据库方案,而不添加其他实体的任何附加属性。

谢谢

【问题讨论】:

据我所知,您需要Class(A|B|C)Course 之间的关系?是两个不同的数据库表吗? 感谢您的回复。是的,它们是 4 个实体(数据库表)。关系应该基于 Course.class_type 【参考方案1】:

解决方案可能是下一个:

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

    

因此,现在您将为您的所有 classes 提供与 course 一对多关系的单个表(这只是一个示例,您可以使用一对多或多对多,具体取决于您的需要)。

在 DQL 中,您可以找出与 INSTANCE OF 一起使用的类。

【讨论】:

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

以上是关于与学说 Symfony 的条件关系的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 和空关系的学说

Symfony学说OneToAll关系

Symfony 固定装置和多对多关系(学说)

如何让 Symfony 2 与学说 ORM 只保留一次相关实体

Symfony学说中的许多关系

symfony 3 学说不接受主键