2012-06-20 10 views
17

Ich versuche, eine Abfrage mit der Lehre Query Builder zu bauen, wie dies eine nicht verwandte Tabelle verbindet:Symfony 2: INNER JOIN auf nicht verwandte Tabelle mit Lehre Query Builder

$query = $this->createQueryBuilder('gpr') 
     ->select('gpr, p') 
     ->innerJoin('TPost', 'p') 
     ->where('gpr.contentId = p.contentId') 

Aber das tut nicht Arbeit. Ich bekomme immer noch einen Fehler:

Error: Identification Variable TPost used in join path expression but was not defined before.

ich für diese Fehlermeldung durchsucht und alle beantwortet die Tabelle alias verwenden + wie p.someAttribute zuzuschreiben. Aber die Tabelle, der ich mich anschließen möchte, ist nicht in der Tabelle verwandt, aus der ich meine Auswahl starte.

Als normale mysql query ich es so schreiben würde:

SELECT * FROM t_group_publication_rel gpr 
INNER JOIN t_post p 
WHERE gpr.content_id = p.content_id 

Irgendwelche Ideen, was ich falsch mache?

+0

Wir können DQL verwenden ausführen ein Join mit nicht verwandten Objekten? Ich weiß es nicht. Wenn möglich, ist es interessant =). – sensorario

+2

Warum baust du nur eine Beziehung zwischen diesen beiden auf, wenn du ihnen beitreten willst? –

+0

In diesem Fall wäre eine Beziehung nicht genug. Ich würde Beziehungen zu 3 verschiedenen Tabellen benötigen, und jeder Datensatz konnte nur einen Verweis auf 1 von diesen 3 setzen. –

Antwort

51

Heute arbeitete ich an ähnlicher Aufgabe und erinnerte mich, dass ich dieses Problem öffnete. Ich weiß nicht, seit welcher Doktrin-Version es funktioniert, aber im Moment können Sie einfach den Unterklassen im Vererbungs-Mapping beitreten. So eine Abfrage wie das funktioniert ohne Probleme:

$query = $this->createQueryBuilder('c') 
     ->select('c') 
     ->leftJoin('MyBundleName:ChildOne', 'co', 'WITH', 'co.id = c.id') 
     ->leftJoin('MyBundleName:ChildTwo', 'ct', 'WITH', 'ct.id = c.id') 
     ->orderBy('c.createdAt', 'DESC') 
     ->where('co.group = :group OR ct.group = :group') 
     ->setParameter('group', $group) 
     ->setMaxResults(20); 

ich die Abfrage in meiner Elternklasse starten, die Vererbung Mapping verwendet. In meinem vorherigen Beitrag war es ein anderer Ausgangspunkt, aber das gleiche Problem, wenn ich mich recht erinnere.

Da es ein großes Problem war, als ich dieses Problem begann, denke ich, könnte es auch für andere Leute interessant sein, die nichts davon wissen.

+0

Danke! Das hat mir wirklich geholfen, ich habe stundenlang gesucht. – Assil

+0

Wenn ich nicht 'MyBundleName: ChildTwo' Repository habe, möchte ich Abfrage mit Tabellenname schreiben, was ist dann die Lösung? –

+0

@MohammadFareed Der Verweis auf die Entität ist kein Repository, es ist entweder eine Zeichenfolge im Format ': ' ODER die FQCN der Entitätsklasse, z. \ AppBundle \ Entity \ ChildTwo :: class –

0

Ein DQL-Join funktioniert nur, wenn in Ihrem Mapping eine Zuordnung definiert ist. In Ihrem Fall würde ich sagen, dass es viel einfacher ist, eine native Abfrage durchzuführen und ResultSetMapping zu verwenden, um Ihre Objekte zu füllen.

2
$dql = "SELECT 
    a, md.fisrtName , md.LastName, mj 
    FROM MembersBundle:Memberdata md 
     INNER JOIN MembersBundle:Address a WITH md = a.empID 
     INNER JOIN MembersBundle:Memberjob mj WITH md = mj.memberData 
      ... 
    WHERE 
     a.dateOfChange IS NULL 
    AND WHERE 
     md.someField = 'SomeValue'"; 

return $em->createQuery($dql)->getResult(); 
+1

Während diese Antwort keine erforderlichen Details enthält, gibt es nichts zu zitieren, da die Dokumentation von Doctrine vollständig über diese Art von Joins nicht verfügt. Das hat für mich funktioniert. Ich weiß genug SQL, um zu analysieren, was beabsichtigt war und nicht genug Lehre, um die Punkte zu verbinden. – eggmatters

3

tritt zwischen Entitäten ohne Verbände waren nicht möglich, bis Version 2.4, in dem Sie ein beliebigen verbinden mit folgenden Syntax erzeugen:

$query = $em->createQuery('SELECT u FROM User u JOIN Blacklist b WITH u.email = b.email'); 

Referenz: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html

+0

Das ist großartig!Beachten Sie, dass in diesem Fall die Klausel 'WITH' benötigt wird, da dies sonst zu einem Syntaxfehler führt. Sie können jedoch einfach eine Dummy-Bedingung verwenden und erhalten im Wesentlichen eine echte Kreuzverbindung, die DQL sonst nicht unterstützt. Zum Beispiel: 'SELECT u FROM Benutzer u JOIN Items i MIT 0 = 0'. Dies kann für komplexe Statistiken nützlich sein. – jlh