2017-01-12 3 views
0

Angenommen, die folgenden zwei Tabellen "Benutzer" und "Freunde";Doktrin 2 QueryBuilder

Beide Spalten in der Freundes-Tabelle entsprechen der ID-Spalte der Benutzer-Tabelle.

Jetzt kann ich einfach Benutzer durch teilweise Namen mit folgenden finden;

$query='jim'; 
$result=$em->getRepository('\User\Entity\User') 
     ->createQueryBuilder('u') 
     ->where('u.name like :match') 
     ->setParameter('match', $query.'%') 
     ->setMaxResults(5) 
     ->getQuery() 
     ->getResult(); 

nun ein Objekt von \ Benutzer \ Entity \ User userA davon aus, wie würde ich einen Teilstring Spiel für alle Benutzer zu tun, die userA nicht Freunde mit bereits ist?

EDITAdded die Definitionen Entity

/** 
* User 
* 
* @ORM\Table(name="user", uniqueConstraints={@ORM\UniqueConstraint(name="name_key", columns={"name"})}) 
* @ORM\Entity 
*/ 
class User 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="bigint", precision=0, scale=0, nullable=false, unique=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=255, precision=0, scale=0, nullable=false, unique=false) 
    */ 
    private $name; 
} 


/** 
* UserFriends 
* 
* @ORM\Table(name="user_friends", indexes={@ORM\Index(name="user_id_key", columns={"user_id"}), @ORM\Index(name="friend_user_id_key", columns={"friend_user_id"})}) 
* @ORM\Entity 
*/ 
class UserFriends 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="bigint", precision=0, scale=0, nullable=false, unique=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var \User\Entity\User 
    * 
    * @ORM\ManyToOne(targetEntity="User\Entity\User") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="friend_user_id", referencedColumnName="id", nullable=true) 
    * }) 
    */ 
    private $friendUser; 

    /** 
    * @var \User\Entity\User 
    * 
    * @ORM\ManyToOne(targetEntity="User\Entity\User") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true) 
    * }) 
    */ 
    private $user; 
}` 
+0

Anstelle von Tabellenspalten können Sie Ihre Entitätsdefinitionen posten? – lxg

Antwort

0

Wir haben es in zwei Schritten tun werde. Zuerst finden wir heraus, welche Benutzer sie sind Freunde mit, dann machen wir eine Abfrage, die sie ausschließt.

Zuerst rufen wir eine ID-Liste der Freunde des Benutzers:

$friendIds = $em->createQuery(" 
    SELECT IDENTITY(uf.user) 
    FROM User\Entity\UserFriends uf 
    WHERE uf.user = :id") 
->setParameter("id", $userId) // $userId is the ID of the target user 
->getResult(); 

$friendIds = array_map("current", $friendIds); // needed for flattening the array 

Jetzt haben wir einfach die Benutzertabelle abfragen, die IDs unserer Freunde ohne:

$notMyFriends = $em->createQuery(" 
    SELECT u 
    FROM User\Entity\User u 
    WHERE u.id != :ownid 
    AND WHERE u.id NOT IN (:friends)") 
->setParameter("ownid", $userId) // $userId is the ID of the target user 
->setParameter("friends", $friendIds) 
->getResult(); 

Ich verwende Ebene DQL hier, aber wenn Sie den Abfrage-Builder bevorzugen, können Sie es auch in eine QB-Methoden-Kette umschreiben.

(Alle oben ist von der Oberseite meines Kopfes, hoffen, dass es funktioniert. Wenn nicht, lassen Sie einen Kommentar und ich werde versuchen, es zu beheben.)


By the way, bitte lassen Sie mich Ihnen ein paar Hinweise in Bezug auf Ihre Entitätsklassen:

  • Entity Klassen immer in Einzahl UserFriendsUserFriend sein sollte.

  • Alle Annotationsparameter name="foobar" sind redundant, da Doctrine Ihre Tabellen, Indizes und Spalten automatisch benennt.

  • Das gleiche gilt für die JoinColumns ... Sie können sie ganz weglassen, es sei denn, Sie möchten das Standardverhalten explizit ändern (was Sie normalerweise nicht tun).

  • nullable=true ist die Standardeinstellung für eine xToOne-Beziehung, daher kann sie auch weggelassen werden.

  • nullable=false und unique=false sind in einem ID-Feld nicht sinnvoll. Der erste ist redundant, der zweite ist unmöglich.

+0

Prost, ich versuche es und melde mich zurück. In Bezug auf die anderen Vorschläge wurden die Entitäten automatisch aus den Datenbanktabellen nach Doktrin generiert. – Moe

+0

Ihre Lösung hat funktioniert, danke, mein Herr! – Moe

+0

Ich bin froh, dass ich helfen konnte. Hat es genau so funktioniert oder hast du meinen Code geändert? Wenn ja, bitte aktualisieren Sie meine Antwort mit Ihren Korrekturen, damit der nächste Typ auch davon profitieren kann. – lxg

Verwandte Themen