有一些实体(地区,国家,城市)使用STI(甚至CTI)。怎么可能把国家转变为城市而留下旧的身份?
Doctrine 2不支持这一点,因为PHP不支持类型转换用户对象。
话虽如此,Doctrine使用鉴别器列来确定要水合的物体类型。如果使用SQL UPDATE更改数据库中discriminator列的值,则下次加载对象时将更改对象类型。这适用于STI,但CTI会更复杂。
标准使用Doctrine可能无法实现,但您可以解决它。如果使用“类元数据”,则可以选择“鉴别器”列。
看一下我创建的Trait来解决我的应用程序中的问题:
namespace App\Doctrine\Repository;
trait DiscriminatorTrait
{
abstract public function getClassMetadata();
abstract public function getEntityManager();
private function updateDiscriminatorColumn($id, $class)
{
$classMetadata = $this->getClassMetadata();
if (!in_array($class, $classMetadata->discriminatorMap)) {
throw new \Exception("invalid discriminator class: " . $class);
}
$identifier = $classMetadata->fieldMappings[$classMetadata->identifier[0]]["columnName"];
$column = $classMetadata->discriminatorColumn["fieldName"];
$value = array_search($class, $classMetadata->discriminatorMap);
$connection = $this->getEntityManager()->getConnection();
$connection->update(
$classMetadata->table["name"],
[$column => $value],
[$identifier => $id]
);
}
}
但是我必须警告你,当你的子类有(很多)额外的字段后,你需要手动填写或清除它们。