【问题标题】:Doctrine: can the same attribute make a relation to two different destination attributes?学说:同一个属性可以与两个不同的目标属性建立关系吗?
【发布时间】:2021-08-25 11:36:32
【问题描述】:

Doctrine(在 Symfony 中)可以实现这种 OneToOne 关系吗?

User                     Time
+----------+             +-------+
| ...      |             | ...   |
| time_id  |o-----+-----o| user  |
|          |      |      | ...   |
| time2_id |o-----+      | type  |
| ...      |             +-------+
+----------+

也就是说,一个用户可能有两个与之关联的不同时间实体: 其中一个 type=0,另一个 type=1。

我本可以将时间分成两个不同的实体,但我认为这样我 可以复制一些代码,因为 Time 实体有一个 eventListener 和更多相关的代码......

我是这样编码的:

class Time
{
...
    /**
     * @ORM\OneToOne(targetEntity=User::class, mappedBy="time, cascade={"persist"})
     * @ORM\OneToOne(targetEntity=User::class, mappedBy="time2", cascade={"persist"})
     */
    private $user;
...}

class User
{
...
    /**
     * @ORM\OneToOne(targetEntity=Time::class, inversedBy="user", cascade={"persist"})
     * @ORM\JoinColumn(name="time_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $time;

    /**
     * @ORM\OneToOne(targetEntity=Time::class, inversedBy="user", cascade={"persist"})
     * @ORM\JoinColumn(name="time2_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $time2;
...}

事实上,我完美地使用了它,但 Symfony 默默地抱怨(在 Symfony 工具栏/Doctrine/Entities Mapping > 映射错误中):

    App\Entity\User     

    The mappings App\Entity\User#time2 and App\Entity\Time#user are inconsistent with each other.

显然,Doctrine 不喜欢 $user 上的第二个 @ORM\OneToOne,并且正在丢弃它。

此代码会导致哪些假设的不当行为?

注意:学说/通用 v2.11

【问题讨论】:

  • 没有任何假设。 Doctrine 正在丢弃您的部分配置,因为它是错误的。而且由于在逻辑上没有定义使用不正确的配置,所以今天它忽略了第二个,但在某些升级时它可能会开始升级第一个,或两者都升级。只需使用正确的映射,就可以省去一些麻烦。
  • 不,您不能将相同的属性用于两个不同的关系(除非是某种继承映射,但这不是您要讨论的内容)。
  • 我怀疑这一点,但另一种解决方案是复制 Time 实体,这会导致更多重复代码:我只是认为这种双重关系是可能的...... :-(

标签: php doctrine-orm doctrine one-to-one


【解决方案1】:

FWIW,只要放弃Inverse relation part,就可以建立这种关系:

User                     Time
+----------+             +-------+
| ...      |             | ...   |
| time_id  |o-----+-----o|       |
|          |      |      |       |
| time2_id |o-----+      | type  |
| ...      |             +-------+
+----------+

实施者:

class Time
{
...
}

class User
{
...
    /**
     * @ORM\OneToOne(targetEntity=Time::class, cascade={"persist"})
     * @ORM\JoinColumn(name="time_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $time;

    /**
     * @ORM\OneToOne(targetEntity=Time::class, cascade={"persist"})
     * @ORM\JoinColumn(name="time2_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $time2;
...}

还有look at this link 用于拥有与反向关系

就我而言,这完全符合我的需求,因为相反的部分适用于以下方法:

$Time->getUser();

我可以预测。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多