【问题标题】:Symfony OneToMany Relationship check if main (One) entity exists if inserting a new child (Many) entitySymfony OneToMany 关系检查是否存在主(一个)实体如果插入一个新的子(多)实体
【发布时间】:2017-09-01 09:17:03
【问题描述】:

每当我保存新的子行时,我是否必须手动检查父 ID 是否确实存在?我原以为 symfony/doctrine 会自动检查并会抛出一个错误,因为因为 OneToMany 定义

例子:

主要实体(“一”):

class Order
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="OrderPayment", mappedBy="orderId")
     */
    private $orderPayments;



    public function __construct()
    {
        $this->orderPayments = new ArrayCollection();
    }

}

子实体(“许多”):

class OrderPayment
{
    /**
     * @ORM\ManyToOne(targetEntity="Order", inversedBy="orderPayments")
     * @ORM\JoinColumn(name="order_id", referencedColumnName="id")
     */
    private $orderId;

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

}

每当我向数据库中插入新的 OrderPayment 行时,Symfony 不应该检查 $orderId 是否确实存在于数据库中,还是我需要手动检查?

【问题讨论】:

  • 您可以将您的订单实体本身传递给 OrderPayment 构造函数。这将确保您没有放弃 OrderPayments。
  • 你能解释一下吗?简单地添加一个传递 Order 的构造函数对我来说没有任何改变。

标签: php symfony doctrine-orm


【解决方案1】:

最好将$orderId 重命名为$order。 Doctrine 将关系视为实体对象,而不是整数。是的,如果你保存 OrderPayment 并且 Order 不存在,Doctrine 会抛出错误!

当您重命名属性、重新生成实体并更新数据库方案时,将订单添加到 orderpayment,如下所示:

$order = // get order from db
$orderPayment = new OrderPayment();
$orderPayment->setOrder($order);
$em->persist($orderPayment);
$em->flush();

【讨论】:

  • targetEntity Annotation 不能完成这项工作吗?目前,即使Order 不存在,我也可以保存每个条目
  • 这并没有错,因为注释就像你说的那样小心。这是一个命名约定。让我问你,你如何将订单添加到 OrderPayment 中?你应该这样做:$orderPayment->setOrder($order); 因为你添加了一个它必须存在的实体对象。当然,您可以在不添加订单的情况下保存 OrderPayment。那么订单在表中将为空
  • 包括订单 ID 在内的所有数据都来自表单字段。很简单:if ($editForm->isSubmitted() && $editForm->isValid()) { $this->getDoctrine()->getManager()->flush();
  • 但是如何用不存在的ID填写订单的表单字段??
  • 这是一个手动输入字段。用户手动查找银行帐户上的付款,然后输入 orderId、值、日期……因此可能是错误的输入。至少它应该检查 orderId 是否存在,然后比较值(这是一个不同的主题)。
【解决方案2】:

您应该将您的 Order 实体本身传递给 OrderPayment 构造函数,因为没有 Order,OrderPayment 就无法存在。

//OrderPayment
public function __construct(Order $order)
{
    $this->order = $order
    $this-createdAt = \DateTime::now();
}

//Controller or Service
$order = $orderRepository->getOrderBySomeField($field);
if ( ! $order){
    throw new HttpNotFoundException();
}
$orderPayment = new OrderPayment ($order);
$em->persist($orderPayment);
$em->flush;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多