Doctrine阻止连接表中的自引用组合

时间:2017-08-03 21:31:57

标签: php mysql symfony doctrine

我想创建实体Room,其中包含两个用户之间的对话,以及额外的唯一字段。我用这种方式实现了它:

/**
 * @ORM\Table(name="chat_rooms")
 * @ORM\Entity(repositoryClass="Cunningsoft\ChatBundle\Repository\RoomRepository")
 */
class Room
{

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User", inversedBy="startedChatting")
     * @ORM\JoinColumn(name="first_user", referencedColumnName="id")
     */
    private $firstUser;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User", inversedBy="joinedChatting")
     * @ORM\JoinColumn(name="second_user", referencedColumnName="id")
     */
    private $secondUser;

User.orm.xml:

<one-to-many target-entity="Cunningsoft\ChatBundle\Entity\Room" mapped-by="firstUser" field="startedChatting">
            <cascade>
                <cascade-persist/>
            </cascade>
        </one-to-many>
        <one-to-many target-entity="Cunningsoft\ChatBundle\Entity\Room" mapped-by="secondUser" field="joinedChatting">
            <cascade>
                <cascade-persist/>
            </cascade>
        </one-to-many>

它工作正常,但在Room侧的创建实例中,我可以创建此记录:

+------------+-------------+
| first_user | second_user |
+------------+-------------+
|          3 |           4 |
|          4 |           3 |
+------------+-------------+

问题是如何防止语义相同的数据重复,哪种方法正确,在数据库或PHP端执行此操作?

1 个答案:

答案 0 :(得分:1)

我认为你在寻找的是: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html

通过在两个属性中添加@Id看起来已经完成了。这将在数​​据库中创建复合主键。这将确保您的表永远不会为每个相应字段的相同两个用户提供多个条目。

这就是你拥有外键或者至少在字段上设置唯一索引的所有谓词。

您不希望尝试使用PHP处理此问题,因为每次需要创建新值时都必须遍历表中的每个值,无论您使用哪个SQL数据库提供程序都应该能够处理起来容易得多。