2017-08-17 4 views
2

Ich habe ein Unternehmen mit einer ManyToMany Beziehung mit der Benutzertabelle:Symfony Querybuilder: zu viele Anfragen

/** 
* @ORM\ManyToMany(targetEntity="User") 
* @ORM\JoinTable(
* name="offer_allowedusers", 
* joinColumns={ 
*  @ORM\JoinColumn(name="offer_id", referencedColumnName="id", onDelete="CASCADE") 
* }, 
* inverseJoinColumns={ 
*  @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE") 
* } 
*) 
*/ 
private $allowedUsers; 

Und in Form, ich mag eine Dropdown-Liste angezeigt werden (select2 verwenden) auszuwählen, die Benutzer können:

enter image description here

, das zu tun, habe ich in Form Gebäude:

->add('allowedUsers', EntityType::class, [ 
     'class' => 'AppBundle\Entity\User', 
     'query_builder' => function (EntityRepository $er) { 
      return $er->createQueryBuilder('u') 
      ->orderBy('u.username', 'ASC'); 
     }, 
     'label' => 'Allowed users', 
     'required' => false, 
     'multiple' => true 
    ]) 

Das Problem ist, dass es eine Abfrage für jeden Benutzer macht, den Benutzernamen zu bekommen ... Also, wenn ich 500 Benutzer haben, macht es 500 Abfragen ...

enter image description here

Wie optimieren und eine einzige Abfrage ausführen, um alle Datensätze abzurufen?

+0

Haben Sie die __toString() - Methode in Ihrer Benutzerklasse implementiert? Diese Methode würde den Benutzernamen – Mz1907

+0

zurückgeben, der '$ this-> username' zurückgibt. Ohne diese würde es die Benutzernamen nicht in der Dropdown-Liste anzeigen –

+0

Haben Sie versucht, ''Choice_label' => 'Benutzername' im Formular Builder-Optionen-Array hinzuzufügen? –

Antwort

4

Explizit erstellen Fügen Sie Ihren QueryBuilder hinzu und wählen Sie den Benutzer und die zugelassenen Benutzer aus.

UPDATE

Sie müssen auch beitreten und Ihr Benutzerprofil und Benutzereinstellungen wählen OneToOne Beziehungen, weil Lehre OneToOne Beziehungen sie ruft automatisch jedes Mal, wenn die Benutzereinheit zu holen.

Die Doctrine documentation talks about, warum es eine zusätzliche Abfrage beim Abrufen der inversen Seite einer Eins-zu-Eins-Beziehung durchführen muss.

->add('allowedUsers', EntityType::class, [ 
    'class' => 'AppBundle\Entity\User', 
    'query_builder' => function (EntityRepository $er) { 
     return $er->createQueryBuilder('u') 
      ->select('u, au, up, us') 
      ->join('u.allowedUsers', 'au') 
      ->join('u.userProfile', 'up') 
      ->join('u.userSettings', 'us') 
      ->orderBy('u.username', 'ASC') 
     ; 
    }, 
    'label' => 'Allowed users', 
    'required' => false, 
    'multiple' => true 
]) 
+0

Du bist ein Genie :) Btw es funktionierte nach dem Entfernen der '-> join ('u.allowedUsers', 'au')' Linie, weil diese Beziehung nicht existiert (die zugelassenen Benutzer sind im Zusammenhang mit dem Angebot, nicht für den Benutzer) –

+1

Gotcha. Ja, die OneToOne Relation hat mich für eine lange Zeit in eine Falle gelockt, und in einem Extremfall habe ich das ORM-Schema geändert, um zu denken, dass es eine OneToMany ist, aber durch Code immer noch wie OneToOne behandelt. Wie auch immer, Joins sind dein Freund :) –

1

Wenn Sie nicht über Anfragen an Ihre „Einheit“, die nicht brauchen allowedUsers die einfachste Art und Weise Modus als EAGER im Annotation Feld zu definieren, würde zu holen explizit holen:

/** 
* @ORM\ManyToMany(targetEntity="User", fetch="EAGER") 
* @ORM\JoinTable(
* name="offer_allowedusers", 
* joinColumns={ 
*  @ORM\JoinColumn(name="offer_id", referencedColumnName="id", onDelete="CASCADE") 
* }, 
* inverseJoinColumns={ 
*  @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE") 
* } 
*) 
*/ 
private $allowedUsers; 
+0

Fertig, aber nichts geändert –

Verwandte Themen