我用两个模型做了一个非常基本的例子。
"Singer" extends from "Person"
我正在使用 class table Inheritance使用这两个模型:
<?php
namespace models;
/**
* @Table(name="persons")
* @entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="type", type="string")
* @DiscriminatorMap({"singer" = "\models\Singer"})
*/
abstract class Person {
/**
* @Id
* @Column(type="integer", nullable=false, name="id_person")
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/** @column(type="string", nullable=false) */
protected $name;
歌手模型长这样:
namespace models;
/**
* @Table(name="singers")
* @entity
*/
class Singer extends Person{
/** @column(type="string", nullable=false) */
protected $gender;
}
工作流程
考虑这种情况。
在数据库中我有这些行:
人员表:
id_person | name | type ----------------------- 1 john singer
歌 watch :
id_person | gender ------------------ 1 pop
我继续删除这位歌手:
$singer = $em->find('models\Singer', 1); $em->remove($singer); $em->flush();
执行上面的代码后,我再次检查数据库,发现:
人员表:
id_person | name | type ----------------------- (empty)
歌 watch :
id_person | gender ------------------ 1 pop
如您所见,子表中的行未按预期删除。
因此,在搜索 doctrine 的文档后,它指出:
When you do not use the SchemaTool to generate the required SQL you should know that deleting a class table inheritance makes use of the foreign key property ON DELETE CASCADE in all database implementations. A failure to implement this yourself will lead to dead rows in the database.
所以,我继续修改 persons 表,如下所示:
ALTER TABLE persons ADD CONSTRAINT fk_persons_1 FOREIGN KEY (id_person) REFERENCES singers (id_person) ON DELETE CASCADE ON UPDATE NO ACTION;
现在,问题变得复杂了:
- 当我删除歌手时,信息仍然存在,甚至 persons 表也被更改以便从歌 watch 中删除。
当我尝试插入一位新歌手时
$singer = new \models\Singer('Zara', 'rock'); $em->persist($singer); $em->flush();
它抛出一个异常:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`practica`.`persons`, CONSTRAINT `fk_persons_1` FOREIGN KEY (`id_person`) REFERENCES `singers` (`id_person`) ON DELETE CASCADE ON UPDATE NO ACTION)' in /var/www/html/doctrine/vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php:138 Stack trace: #0 /var/www/html/doctrine/vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php(138): PDOStatement->execute(NULL) #1 /var/www/html/doctrine/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php(165): Doctrine\DBAL\Statement->execute() #2 /var/www/html/doctrine/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(929): Doctrine\ORM\Persisters\JoinedSubclassPersister->executeInserts() #3 /var/www/html/doctrine/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(318): Doctrine\ORM\UnitOfWork->executeInserts(Object(Doctrine\ORM\Mapping\ClassMetadata)) #4 /var/www/html/doctrine/vendor/doct in /var/www/html/doctrine/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php on line 47
所以,基本上,我只需要删除 MySQL 数据库中子表中的信息。但是我不明白。
最佳答案
尝试反转FOREIGN KEY
,即将它从你的 persons 表中删除并添加到你的 singers 表中
ALTER TABLE singers
ADD CONSTRAINT fk_singers_1
FOREIGN KEY (id_person)
REFERENCES persons (id_person)
ON DELETE CASCADE
ON UPDATE NO ACTION;
关于php - 使用 Doctrine 中的类表继承从子表中删除行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23974248/