2016-02-15 1 views
2

Je travaille avec Symfony2 et Doctrine et j'ai une question concernant les entités. Dans un soucis de performance, je me demande s'il est possible d'utiliser une entité sans passer par toutes les associations?Entités Symfony sans relationnel

Actuellement, je n'ai pas trouvé un autre moyen de créer un modèle héritant de la classe avec des associations et des associations qui spécifient NULL dans la classe qui hérite.

vous remercie à l'avance


OK, un peu de détails, il est une API REST (JSON).

C'est ma classe:

/** 
* Offerequipment 
* 
* @ORM\Table(name="offer_equipment") 
* @ORM\Entity(repositoryClass="Charlotte\OfferBundle\Repository\Offerequipment") 
*/ 

class Offerequipment 
{ 
/** 
* @var integer 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
private $id; 

/** 
* @ORM\ManyToOne(targetEntity="Charlotte\OfferBundle\Entity\Offer") 
* @ORM\JoinColumn(name="offer_id", referencedColumnName="id") 
*/ 
private $offer; 

/** 
* @ORM\ManyToOne(targetEntity="Charlotte\ProductBundle\Entity\Equipment") 
* @ORM\JoinColumn(name="equipment_id", referencedColumnName="id") 
*/ 
private $equipment; 

/** 
* @VirtualProperty 
* 
* @return String 
*/ 
public function getExample() 
{ 
    return $something; 
} 

et avec la méthode QueryBuilder, je ne peux pas obtenir mes propriétés virtuelles ou getters.

Merci pour votre aide :)

+0

Voulez-vous dire, vous voulez empêcher la sélection d'entités associées lors de la sélection d'une entité particulière avec QueryBuilder? – BentCoder

+0

Si oui, alors pour éviter le chargement paresseux/sélection des entités associées directement dans votre requête, vous pouvez ajouter '...-> getQuery() ...-> setHint (Query :: HINT_FORCE_PARTIAL_LOAD, true) ...-> getResult(); 'méthode à votre constructeur de requête. [Quelques bonnes pratiques de doctrine et charge paresseuse] (http://www.inanzzz.com/index.php/post/5muq/some-doctrine-best-practises-and-lazy-load) et [HINT_FORCE_PARTIAL_LOAD] (http://www.doctrine-project.org/api/orm/2.3/class-Doctrine.ORM.Query.html#HINT_FORCE_PARTIAL_LOAD) – BentCoder

+0

Oui, je veux obtenir une seule entité associée, pas toutes. (par exemple: je veux l'entité de l'équipement et non l'entité de l'offre et conserve la propriété virtuelle de mon équipement) – Vincent

Répondre

2

Regardez la sérialisation. En sérialisant vos entités, vous pouvez choisir d'exclure ou d'exposer une propriété d'une entité lorsque vous la restituez. Voir le Symfony built-in Serializer et/ou le JMSSerializer. Sinon, vous pouvez utiliser QueryBuilder et DQL pour choisir les champs que vous souhaitez extraire dans vos requêtes.

Ainsi, vous pouvez créer votre propre méthode find dans les entités Repository de vos entités.

// src/AcmeBundle/Repository/FooRepository 

class FooRepository extends \Doctrine\ORM\EntityRepository 

    // ... 

    public function find($id) { 
     $queryBuilder = $this->createQueryBuilder('e') 
      ->select('e.fieldA', 'e.fieldB') // selected fields 
      ->where('e.id = :id') // where statement on 'id' 
      ->setParameter('id', $id); 

     $query = $queryBuilder->getQuery(); 

     $result = $query->getResult(); 
    } 

    // ... 
} 

Ne pas oublier de définir le Repository dans le Entity correspondant.

/** 
* Foo. 
* 
* @ORM\Entity(repositoryClass="AcmeBundle\Repository\FooRepository") 
*/ 
class Foo 
{ 
    // ... 
} 
+0

Merci Chalasr, mais j'ai @VirtualProperty et cela ne fonctionne pas avec select ou addSelect. – Vincent

1

par la doctrine par défaut ne récupérera automatiquement toutes les associations dans vos entités, sauf si vous spécifiquement chaque association EAGER ou à moins que vous utilisez une association OneToOne. Donc, si vous cherchez à éliminer les JOINs, vous pouvez simplement utiliser Doctrine dans son état par défaut et il ne JOINDRE rien automatiquement.

Cependant, vous cela ne permettra pas d'atténuer tous vos problèmes de performance. Supposons, par exemple, que vous affichiez une liste de 50 produits dans votre application sur une seule page et que vous souhaitiez afficher leurs remises possibles, où les remises sont associées à votre entité de produit. Doctrine créera 50 requêtes supplémentaires uniquement pour récupérer les données de réduction, à moins que vous ne joignez explicitement l'entité de réduction dans votre requête. Essentiellement, le profileur Symfony sera votre ami et vous montrera quand vous devriez rejoindre des entités sur votre requête - ne pensez pas que parce que vous ne rejoignez pas automatiquement les associations, vos performances seront toujours meilleures.

1

Enfin, après plusieurs jours, j'ai trouvé la solution pour sélectionner une seule entité.

VirtualProperties sont trouvés :)

public function findAllByOffer($parameters) 
{ 
    $queryBuilder = $this->createQueryBuilder('oe'); 
    $queryBuilder->select('oe, equipment'); 
    $queryBuilder->join('oe.equipment', 'equipment'); 

    $result = $queryBuilder->getQuery()->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)->getResult(); 

    return $result; 
}