【问题标题】:How to add one-to-many FK that can be null如何添加可以为空的一对多 FK
【发布时间】:2020-01-15 20:20:34
【问题描述】:

我正在尝试两个实体 A 和 B 之间的 ManyToOne 基本关系。实体 A 已经被声明,因此实际迁移包含实体 B 的创建以及以某种方式更改 A 以接受外键。我也遇到了这里显示的问题:Not able to define column type in JoinColumn for a foreign key reference in Symfony2/Doctrine(具有 A bigint 的 PK,cannot add foreign key 出错)。

修复了这个问题,只有当我删除实体 A 并基本上从头开始创建它们时它才有效。 我的代码和迁移只创建了 B 并更改了 A (仍然会导致错误): 不知何故,我希望 A 的 FK 也接受可为空的值,我认为问题在于:

这是第一次迁移:

CREATE TABLE
 A(id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL,
 name VARCHAR(255) NOT NULL,
 description VARCHAR(255) NOT NULL,
 value VARCHAR(255) NOT NULL,
 datatype VARCHAR(255) NOT NULL,
PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB

现在根据我的代码正在生成以下查询:

CREATE TABLE 
 B(id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL,
 name VARCHAR(255) NOT NULL,
 code INT UNSIGNED NOT NULL,
 UNIQUE INDEX code_idx (code),
 PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB

和:

ALTER TABLE
 A(table) ADD CONSTRAINT FK_D1DD32EBBF396750 FOREIGN KEY (id) REFERENCES B(table) (id)

但是当我运行迁移时,A 表中没有放置任何列。我真的很困惑,不知道如何解决这个问题。有人有线索吗?

编辑:

我在实体中的代码是:

class A:

/**
 * @var B
 *
 * @ORM\ManyToOne(targetEntity="App\Model\B", inversedBy="aS")
 * @ORM\JoinColumn(name="id", referencedColumnName="id")
 */
private $bId;

class B:
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="bigint", nullable=false, options={"unsigned": true})
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

/**
 * @ORM\OneToMany(targetEntity="App\Model\A", mappedBy="bid")
 */
private $aS;

【问题讨论】:

  • 您的ALTER TABLE 在逻辑上是错误的。您尝试将一个主键引用到另一个主键。 1)每个主键都是唯一的,因此您可能会获得一对一,而不是一对多。 2) 该表不能通过自增字段引用另一个表。
  • 在表A结构中添加一个字段并将其引用到表B,如ALTER TABLE A ADD COLUMN table_B_id BIGINT UNSIGNED NOT NULL, ADD CONSTRAINT FK_D1DD32EBBF396750 FOREIGN KEY (table_B_id) REFERENCES B (id)
  • 我添加了一个编辑。基本上这是我的代码,生成的查询是由教义产生的。
  • @Akina 我已经按照你的建议做了,它正在工作,但我不知道如何在教义代码中转换它以生成你的查询..
  • 我对教义的唯一了解就是它的存在。

标签: mysql


【解决方案1】:

您的映射有点缺陷(或者您实际上打算这样做)
这是您的代码已修复

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="a")
 * @ORM\Entity(repositoryClass="App\Repository\ARepository")
 */
class A
{
    /**
     * @var B
     *
     * @ORM\ManyToOne(targetEntity="B", inversedBy="aS")
     * @ORM\JoinColumn(name="id", referencedColumnName="id")
     * @ORM\Id
     */
    private $bId;
}

这是首选的解决方案

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="a")
 * @ORM\Entity(repositoryClass="App\Repository\ARepository")
 */
class A
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="bigint", options={"unsigned": true})
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="auto")
     */
    private $id;

    /**
     * @var B
     *
     * @ORM\ManyToOne(targetEntity="B", inversedBy="aS")
     * @ORM\JoinColumn(name="b_id", referencedColumnName="id")
     */
    private $b;
}

在您的 A 实体中,您实际上映射对象 B 而不是它的 ID

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 2019-03-22
    • 1970-01-01
    • 2022-01-20
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多