Как конвертировать сущность, оставив ее id - PullRequest
3 голосов
/ 07 июня 2011

Есть некоторые объекты (Регион, Страна, Город), которые использовали STI (или даже CTI). Как можно преобразовать страну в город, оставив старый идентификатор?

Ответы [ 2 ]

4 голосов
/ 13 июня 2011

Это не поддерживается в Doctrine 2, потому что PHP-преобразование типов объектов не поддерживается PHP.

С учетом вышесказанного, Doctrine использует столбец дискриминатора, чтобы определить тип гидратируемого объекта. Если вы измените значение столбца дискриминатора в базе данных с помощью SQL UPDATE, тип объекта будет изменен при следующей загрузке объекта. Это работает для ИППП, но CTI будет более сложным.

0 голосов
/ 18 февраля 2019

Это может быть невозможно при стандартном использовании Doctrine, но вы можете обойти это. Если вы используете метаданные класса, вы можете выбрать свой столбец дискриминатора.

Взгляните на черту, которую я создал, чтобы решить проблему в моем приложении:

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]
        );
    }
}

Я должен предупредить вас, хотя, когда ваши подклассы имеют (много) дополнительных полей, вам нужно будет заполнить или очистить их вручную впоследствии.

...