Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Doctrine orm 博士2预先删除一个域名_Doctrine Orm - Fatal编程技术网

Doctrine orm 博士2预先删除一个域名

Doctrine orm 博士2预先删除一个域名,doctrine-orm,Doctrine Orm,在我的模型中,我有 Terrain.php Lot.php 很多 我试图删除一个地形,但以前我删除了所有与之相关的地块。当我尝试删除地形时,我得到一个错误SQLSTATE[23000]:完整性约束冲突在删除时,您仍然有一个从地块到地形的引用,这就是为什么您有完整性约束冲突 试试这个: /** * @ORM\Entity * @ORM\HasLifecycleCallbacks() */ class Terrain { /** * @var lots * * @OR

在我的模型中,我有

Terrain.php Lot.php 很多


我试图删除一个地形,但以前我删除了所有与之相关的地块。当我尝试删除地形时,我得到一个错误
SQLSTATE[23000]:完整性约束冲突

在删除时,您仍然有一个从
地块
地形
的引用,这就是为什么您有
完整性约束冲突

试试这个:

/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks()
*/
class Terrain
{
    /**
    * @var lots
    *
    * @ORM\OneToMany(targetEntity="Lot", mappedBy="terrain")
    */
    private $lotes;

    /**
    * @ORM\PreRemove
    */
    public function deleteAllLots()
    {
        $lots = $this->getLots();

        foreach ($lots as $lot) {
            $this->lots->removeElement($lot);
            $lot->terrain = null; //$lot->setTerrain(null); will be better, try to add getters and setters
        }
    }
}
如果要从数据库中删除
lots
,应使用
OneToMany
relation()的
cascade
属性,如下所示:

/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks()
*/
class Terrain
{
    /**
    * @var lots
    *
    * @ORM\OneToMany(targetEntity="Lot", mappedBy="terrain", cascade={"remove"})
    */
    private $lotes;
}
Terrain
remove上,所有地块都将被删除。

发布的第一个代码也不会删除第二个表中的数据,它只是将引用置空,如果您只依赖一个实体,通常该值永远不应为空(在该表中不应该有任何没有引用的旧行,因为在大多数情况下,您无法使用它们,它只会让该表充满您不需要的内容,并破坏索引)

从:

生命周期回调是在触发事件时调用的实体类上的方法。它们绝对不接收任何参数,并且专门设计为允许在实体类状态内进行更改。 生命周期事件侦听器是具有特定回调方法的类,这些回调方法接收某种类型的>EventArgs实例,这些实例允许访问实体、EntityManager或其他相关数据

生命周期回调仅用于更改该实体,而不是它引用的其他实体。 您必须使用生命周期事件侦听器,而不是生命周期回调。 使用生命周期事件侦听器,您可以访问实体管理器并删除这些实体。 但正确的方法是在引用上使用delete cascade,这样就可以忽略引用的对象(不必在1次操作后从数据库中读取它们来删除它们),并让数据库处理它们。 您只需更改这一行:

@ORM\JoinColumn(name="terrain_id", referencedColumnName="id")
对此

@ORM\JoinColumn(name="terrain_id", referencedColumnName="id", onDelete="cascade")
您可以在JoinColumn注释上找到文档


您可以使用cascade=“remove”建议使用OneToMany注释上的参数,但速度要慢得多。

为什么不使用PostRemove而不是PreRemove?这种方法可以在地块后删除地形,而不会违反数据库完整性。删除地块后,现在可以安全地删除相关地形

/**
 * @ORM\PostRemove
 */
public function deleteTerrain(\Doctrine\ORM\Event\LifecycleEventArgs $args)
{
    $em = $args->getEntityManager();

    $terrain = $this->getTerrain();
    $em->remove($terrain);
    $em->flush();
}

我知道注释中的oroperty级联,但我正在尝试用生命周期调用backshot来解决这一问题,这就是为什么我在第一个代码中解释了如何在没有级联注释的情况下正确删除批次。您尝试过吗?
@ORM\JoinColumn(name="terrain_id", referencedColumnName="id", onDelete="cascade")
/**
 * @ORM\PostRemove
 */
public function deleteTerrain(\Doctrine\ORM\Event\LifecycleEventArgs $args)
{
    $em = $args->getEntityManager();

    $terrain = $this->getTerrain();
    $em->remove($terrain);
    $em->flush();
}