Php 作为复合主键的外键

Php 作为复合主键的外键,php,postgresql,doctrine-orm,symfony,Php,Postgresql,Doctrine Orm,Symfony,我正在尝试使用doctrine2将以下PostgreSQL代码实现到php中 create table tournaments ( id serial primary key, tournament_name text not null, start_time timestamp not null, end_time timestamp not null ); create table group_slots ( id serial, tournament_id int references

我正在尝试使用doctrine2将以下PostgreSQL代码实现到php中

create table tournaments (
id serial primary key,
tournament_name text not null,
start_time timestamp not null,
end_time timestamp not null
);

create table group_slots (
id serial,
tournament_id int references tournaments,
start_time timestamp not null,
end_time timestamp not null,
primary key(id, tournament_id)
);
正如您所注意到的,锦标赛和组槽表之间需要有一个双向关系,
OneToMany
,其中
tourbank\u id
是被引用的列。以下是我到目前为止的情况:

锦标赛
实体:

<?php

namespace SportsBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use SportsBundle\Entity\GroupSlots;

/**
 * Tournaments
 *
 * @ORM\Table(name="tournaments")
 * @ORM\Entity(repositoryClass="SportsBundle\Repository\TournamentsRepository")
 */
class Tournaments {

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     *
     * @var string
     *
     * @ORM\Column(name="tournament_name", type="string", nullable=false)
     */
    protected $tournament_name;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="start_time", type="datetime", nullable=false)
     */
    protected $start_time;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="end_time", type="datetime", nullable=false)
     */
    protected $end_time;

    /**
     * @ORM\OneToMany(targetEntity="GroupSlots", mappedBy="tournament")
     */
    protected $groupslots;

    /**
     * @return ArrayCollection
     */
    public function __construct() {
        $this->groupslots = new ArrayCollection();
    }

}
<?php

namespace SportsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use SportsBundle\Entity\Tournaments;

/**
 * GroupSlots
 *
 * @ORM\Table(name="group_slots")
 * @ORM\Entity(repositoryClass="SportsBundle\Repository\GroupSlotsRepository")
 */
class GroupSlots {

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="start_time", type="datetime", nullable=false)
     */
    protected $start_time;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="end_time", type="datetime", nullable=false)
     */
    protected $end_time;

    /**
     * @ORM\ManyToOne(targetEntity="Tournaments", inversedBy="groupslots")
     * @ORM\JoinColumn(name="tournament_id", referencedColumnName="id")
     */
    protected $tournament;

}
<?php

namespace SportsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use SportsBundle\Entity\Tournaments;

/**
 * GroupSlots
 *
 * @ORM\Table(name="group_slots")
 * @ORM\Entity(repositoryClass="SportsBundle\Repository\GroupSlotsRepository")
 */
class GroupSlots {

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="start_time", type="datetime", nullable=false)
     */
    protected $start_time;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="end_time", type="datetime", nullable=false)
     */
    protected $end_time;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Tournaments", inversedBy="groupslots")
     * @ORM\JoinColumn(name="tournament_id", referencedColumnName="id")
     */
    protected $tournament;

}
问题:

我无法以标准方式对引用列使用
@ORM\Id
。如何在GroupSlots实体中创建复合主键,包括
id
和引用的列
tournament\u id

编辑:

我尝试将
@Id
添加到
$tournament
属性中,如文档中所示

以下是更新后的
GroupSlots
实体:

<?php

namespace SportsBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use SportsBundle\Entity\GroupSlots;

/**
 * Tournaments
 *
 * @ORM\Table(name="tournaments")
 * @ORM\Entity(repositoryClass="SportsBundle\Repository\TournamentsRepository")
 */
class Tournaments {

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     *
     * @var string
     *
     * @ORM\Column(name="tournament_name", type="string", nullable=false)
     */
    protected $tournament_name;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="start_time", type="datetime", nullable=false)
     */
    protected $start_time;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="end_time", type="datetime", nullable=false)
     */
    protected $end_time;

    /**
     * @ORM\OneToMany(targetEntity="GroupSlots", mappedBy="tournament")
     */
    protected $groupslots;

    /**
     * @return ArrayCollection
     */
    public function __construct() {
        $this->groupslots = new ArrayCollection();
    }

}
<?php

namespace SportsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use SportsBundle\Entity\Tournaments;

/**
 * GroupSlots
 *
 * @ORM\Table(name="group_slots")
 * @ORM\Entity(repositoryClass="SportsBundle\Repository\GroupSlotsRepository")
 */
class GroupSlots {

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="start_time", type="datetime", nullable=false)
     */
    protected $start_time;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="end_time", type="datetime", nullable=false)
     */
    protected $end_time;

    /**
     * @ORM\ManyToOne(targetEntity="Tournaments", inversedBy="groupslots")
     * @ORM\JoinColumn(name="tournament_id", referencedColumnName="id")
     */
    protected $tournament;

}
<?php

namespace SportsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use SportsBundle\Entity\Tournaments;

/**
 * GroupSlots
 *
 * @ORM\Table(name="group_slots")
 * @ORM\Entity(repositoryClass="SportsBundle\Repository\GroupSlotsRepository")
 */
class GroupSlots {

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="start_time", type="datetime", nullable=false)
     */
    protected $start_time;

    /**
     *
     * @var datetime
     *
     * @ORM\Column(name="end_time", type="datetime", nullable=false)
     */
    protected $end_time;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Tournaments", inversedBy="groupslots")
     * @ORM\JoinColumn(name="tournament_id", referencedColumnName="id")
     */
    protected $tournament;

}

有什么想法吗?

您的复合密钥似乎是多余的,因为您已经在组\u插槽中使用了一个串行列。每一行的ID总是不同的,因此无论比赛ID是否包含在密钥中,每一行都是唯一的。您是否试图对某些限制进行建模,例如“给定锦标赛没有重叠的时间段”?如果是这样的话,在密钥中使用锦标赛ID是不行的。您可能需要研究另一种方法来实施您试图建模的规则,例如一组检查约束,服务器端功能,甚至客户端验证。@GordonM还有一个名为
组的表
,它需要与
组\u插槽
具有相同的锦标赛id,因此存在一种外键关系,如
外键(组\u插槽id,锦标赛\u id)引用组\u插槽(id,锦标赛\u id),
因此比赛id和id需要设置为“唯一”或“主要”,以便将其作为外键,因此我们决定在今年使用它way@GordonM是的,我们也有检查限制,在博士后方面没有问题,只是条令不好:)我怀疑条令根本不支持你想做的事情。这就是ORM的问题所在(很多问题中的一个,但这是另一个讨论)。它们很少支持底层数据库所能使用的每一种可能的用例,尤其是ORM开发人员没有考虑的用例。您的复合密钥似乎是多余的,因为您已经在GROPSPY时隙中使用了一个串联列。每一行的ID总是不同的,因此无论比赛ID是否包含在密钥中,每一行都是唯一的。您是否试图对某些限制进行建模,例如“给定锦标赛没有重叠的时间段”?如果是这样的话,在密钥中使用锦标赛ID是不行的。您可能需要研究另一种方法来实施您试图建模的规则,例如一组检查约束,服务器端功能,甚至客户端验证。@GordonM还有一个名为
组的表
,它需要与
组\u插槽
具有相同的锦标赛id,因此存在一种外键关系,如
外键(组\u插槽id,锦标赛\u id)引用组\u插槽(id,锦标赛\u id),
因此比赛id和id需要设置为“唯一”或“主要”,以便将其作为外键,因此我们决定在今年使用它way@GordonM是的,我们也有检查限制,在博士后方面没有问题,只是条令不好:)我怀疑条令根本不支持你想做的事情。这就是ORM的问题所在(很多问题中的一个,但这是另一个讨论)。它们很少支持底层数据库所能使用的每种可能的用例,尤其是ORM开发人员没有考虑的用例。