Doctrine复合主键外键

8

我正在使用Symfony 2从现有数据库创建一个Web应用程序。

我已经设置了一个实体,它的主键由两个外键组成。

例如:

Entity1具有组合主键:property1(PK),property2(PK) Entity2的主键由两个外键property1(PK FK),property2(PK FK),propriete3(PK)组成

我不知道如何实现这种关联:

在entity2中,我这样做:

/** 
 * @ORM\ManyToOne (targetEntity = "Entity1") 
 * @ORM\JoinColumns ({
 *    @ORM\JoinColumn (name = "property1" referencedColumnName = "property1") 
 *    @ORM\JoinColumn (name = "property2" referencedColumnName = "property2") 
 *    @ORM\Id 
 * @}) 
 */ 
private $entity1; 

但是我遇到了一个错误:
不可能将实体 'ExempleBundle\Entity\Entite1' 作为另一个实体 'ExempleBundle\Entity\Entite2#entite1' 的主键的一部分与复合主键映射。
如何正确处理这种关联关系和Doctrine?
我尝试跟随这个例子,但我不明白:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html#use-case-1-dynamic-attributes 你能否给出两个实体的类似情况的示例,特别是在这种情况下如何进行关联。
3个回答

5
我发现一个解决方法可以避免这个问题,通过定义一个单独的外键,使用原始的外键列作为连接列。
/** @Id @Column(...) */
protected $property1;
/** @Id @Column(...) */
protected $property2;
/** @Id @Column(...) */
protected $property3;

/**
 * @ManyToOne(targetEntity="Entity1")
 * @JoinColumns({
 *     @JoinColumn(name="property1", referencedColumnName="property1"),
 *     @JoinColumn(name="property2", referencedColumnName="property2")
 * })
 **/
protected $foreignObject;

谢谢,但是如果我设置(例如)$property1、$property2和$property3,这些字段就会变成null。在删除$foreignObject之后,它可以正常工作。有没有办法同时使用两者? - schellingerht

2

It is a example that works:

<?php

namespace Project\WorkflowBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="opinion")
 */
class Opinion
{
    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="\Project\WorkflowBundle\Entity\Comision_Proyecto", inversedBy="opiniones")
     */
    protected $comision;
    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="\Project\WorkflowBundle\Entity\Persona", inversedBy="opiniones")
     */
    protected $persona;
    /**
     * @ORM\OneToMany(targetEntity="\Project\WorkflowBundle\Entity\Comentario", mappedBy="opinion")
     */
    protected $comentarios;
}

另一个类:

<?php


namespace Project\WorkflowBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="comentario")
 */
class Comentario
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    protected $id;
    /**
     * @ORM\Column(type="boolean")
     */
    protected $privado;
    /**
     * @ORM\ManyToOne(targetEntity="\Project\WorkflowBundle\Entity\Opinion")
     *  @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="comision_id", referencedColumnName="comision_id"),
     *   @ORM\JoinColumn(name="persona_id", referencedColumnName="persona_id")
     * })
     */
    protected $opinion;
}

你的解决方案行不通,因为在迁移过程中会出现 FOREIGN KEY (opinion_id) REFERENCES opinion (comision_id, persona_id)。 - Serhii Smirnov

-1

Doctrine2无法管理外键复合主键以引用具有其复合主键的实体

Doctrine2正确处理复合主键的情况主要包括:

  • OneToMany:关联实体(ArticleAttributes)使用作为主键的被引用实体(Artile)的主键和另一个自身字段(attribute)

文章(id,标题,...), 文章属性(#article_id,#attribute,value,...)

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html#use-case-1-dynamic-attributes

在您的情况下,您想引用一个没有唯一标识符而是复合键的实体,Doctrine不管理此情况。您只能为关联实体类型拥有复合键。

通常,我避免在主要模型中使用复合键。我将复合键保留给关联类型的模型。

因此,解决方案是为您的主模型Entity1使用主键。

希望这可以帮助到您。


看起来你错了,Doctrine通过复合键管理关联。这不是问题。问题在于用于关联的键似乎不能同时成为PK的一部分,这是错误的:无法将实体'...'映射为另一个实体'...'的主键的一部分,因为它具有复合主键。对于这种情况,有一个丑陋的解决方案: http://stackoverflow.com/questions/19008582/doctrine2-map-entities-with-composite-foreign-keys-in-the-composite-primary-keys - zelibobla
请正确阅读我的回答,我从未说过“Doctrine [不]通过复合键来管理关联”。相反,我说过Doctrine2在某些情况下可以正确地管理复合主键。 - BADAOUI Mohamed
在我看来,我不认为你期望的内容是可能的。只有我提到的情况才能被Doctrine 2很好地管理。 - BADAOUI Mohamed

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