12
votes

Comment changer et tout type d'entité dans la doctrine2 CTI Héritage

Comment (si possible du tout) modifiez-vous le type d'entité avec Doctrine2 en utilisant son héritage de la table de classe?

Disons que j'ai une personne personne type parent et deux types hérités employeur et client . Mon système permet de créer une personne et de spécifier son type - c'est assez facile à mettre en œuvre - mais j'aimerais également pouvoir modifier la personne d'un employé à un client, tout en maintenant la personne - Informations de niveau (ID ID et autres enregistrements associés).

Y a-t-il un moyen simple de le faire avec Doctrine2?


0 commentaires

4 Réponses :


1
votes

en doctrine2, lorsque vous avez votre classe d'entité parent, personne défini comme suit: xxx

et sous des classes telles que Client défini Comme: xxx

Lorsque vous instaniez personne comme: xxx

doctrine2 vérifie votre @DiscriminatorMapap Énoncé (ci-dessus) pour un mappage correspondant à Personne et lorsque trouvé, crée une valeur de chaîne dans la colonne Table enfoncée dans @discriminatorcolumn ci-dessus. < / p>

Ainsi, lorsque vous décidez d'avoir une instance de Client comme: xxx

suivant ces principes, doctrine2 créera une instance pour Vous aussi longtemps que vous avez déclaré les paramètres dans le @DiscriminatorMap . Une entrée sera également faite sur la table de la personne , dans la colonne discriminatoire pour refléter ce type de classe d'entité qui vient d'être instancié.

espoir qui aide. C'est tout dans le Documentation bien que


1 commentaires

Peut-être que ma question n'était pas assez claire mais j'aimerais lancer une entité d'un type dans un autre type (c.-à-d. Client -> employé) tout en conservant les données générales relatives à la superclasse (personne ici ). En outre, j'utilise un héritage de table unique pour celui-ci (pas de table multiple)



7
votes

Je cherchais ce comportement hier aussi.

À la fin, après avoir parlé avec des personnes à #Doctrine sur Freenode, on m'a dit que ce n'est pas possible.

Si vous voulez faire cela, vous devez passer à travers ceci:

Mise à niveau d'un utilisateur
  1. saisir l'entité de la personne.
  2. Mettez à jour la colonne discriminator pour qu'il ne soit plus une «personne» et la modifier à «Employee»
  3. Créer une ligne correspondante Inyour Employee Table de cette héritage.

    Suppression de l'héritage

    De même si vous voulez supprimer l'héritage, vous devez ..

    1. saisir l'entité de la personne.
    2. Mettez à jour la colonne discriminator pour qu'il ne soit plus un «employé» et la modifier à une «personne».
    3. Supprimez la ligne correspondante dans votre Table de l'employé . (Oui, vous devez le supprimer, changez simplement que le discriminateur Coumn n'est pas suffisant).

      Cela pourrait être de 7 mois de retard, mais c'est au moins la bonne réponse pour tout ce qui cherche à suporter une telle fonctionnalité.


2 commentaires

Impressionnant. J'ai fini par n'utiliser pas CTI pour ce problème spécifique, mais cela pourrait effectivement être nécessaire quelque while =)


Qu'en est-il de rafraîchir l'entité? Si vous avez déjà chargé l'entité utilisateur, la valeur discriminatrice manuelle ne fera pas partie de l'entité utilisateur déjà chargée gérée par l'unité de travail. Donc, l'entité utilisateur sera toujours considérée comme l'ancien type. $ em-> Actualiser ($ utilisateur); ne marche pas. Alors, comment faire face à ce problème?



4
votes

php n'a pas de support pour la coulée d'objet, la doctrine ne le supporte pas. Pour contourner le problème, j'écris cette méthode statique dans les classes parent:

$employe = New Employe();
$client = Client::castToMe($employe);


0 commentaires

1
votes

Vous pouvez faire quelque chose comme ça, cependant:

Ce trait peut être utilisé sur votre classes de référentiel: P>

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


0 commentaires