2013-02-19 10 views
7

Spojrzałem na wiele odpowiedzi związanych z tym, co wydaje się być poważnym brakiem funkcjonalności w Doctrine 2.1, który może być wynikiem poprawności OOP wyłamywać relacyjne zdrowie psychiczne.Doctrine 2.1 gdzie klucz obcy id = ?, edytuj: Naprawiono w Doctrine 2.2

Mam dwie tabele z wieloma relacjami, artykułami i członkami. Członek może mieć wiele opublikowanych artykułów. Adnotacja na stronie posiadanie jest

/** 
* @var \Member 
* @ORM\ManyToOne(targetEntity="Member") 
* @ORM\JoinColumns({ 
* @ORM\JoinColumn(name="member_id", referencedColumnName="id") 
* }) 
*/ 
private $member; 

chcę uzyskać wszystkie aktywne artykuły do ​​członka 6, to jest proste zapytanie w SQL:

SELECT * FROM mbr_article 
    WHERE active = 1 AND member_id = 6 
    ORDER BY article_id DESC 

Co skończyło się było

$rep = $this->getDoctrine()->getRepository('SMWMemberBundle:Article'); 
$q = $rep->createQueryBuilder('a') 
    ->leftJoin('a.member','m')  
    ->where('m.id = ?1') 
    ->andWhere('a.active = 1') 
    ->orderBy('a.id', 'DESC') 
    ->setParameter(1, $id)  
    ->getQuery(); 

które generowane

SELECT m0_.id AS id0, m0_.active AS active1, m0_.update_time AS update_time2, 
     m0_.content AS content3, m0_.member_id AS member_id4 
    FROM mbr_article m0_ 
    LEFT JOIN mbr_member m1_ ON m0_.member_id = m1_.id 
    WHERE m1_.id = ? AND m0_.active = 1 
    ORDER BY m0_.id DESC 

który działa i prawdopodobnie nie jest dużo wolniejszy, ale to JOIN nie jest potrzebne, ponieważ już mam obiekt Member. Kiedy spróbowałem tego w inny sposób, wszystkie artykuły były nie tylko aktywne.

Widziałem odpowiedzi, takie jak Can you get a foreign key from an object in Doctine2 without loading that object?, które używają getEntityIdentifier i wspomina o ulepszeniach nadchodzących w 2.2, gdzie mogę powiedzieć IDENTITY(member).

Czy istnieje rozsądny sposób, aby to zrobić w Doctrine 2.1? Czy to ulepszenie pozwoli na utworzenie andWhere('IDENTITY(member) = ?') w Kreatorze zapytań?

EDIT:

Dzięki @Ocramius, -> where ('? IDENTITY (a.member) = 1') działa w doktrynie 2,2

+0

Przede wszystkim należy wziąć pod uwagę, że 2.1 nie ma już wsparcia: należy rozważyć aktualizację. W każdym razie pobranie identyfikatora z serwera proxy nie powoduje jego załadowania, jeśli nazwa metody to 'get '. ucfirst ($ fieldName) ' – Ocramius

+0

@Ocramius Dziękuję,' -> where ('TOŻSAMOŚĆ (a.member) =? 1') 'działa w Doctrine 2.2, czy mógłbyś to opublikować jako odpowiedź, a ja to zaakceptuję . –

+0

Dodaj to sam i zaakceptuj, po tym wszystkim, że sam znalazłeś rozwiązanie;) – Ocramius

Odpowiedz

20

TOŻSAMOŚĆ pracuje w WHERE generowane przez konstruktora zapytań w Doctrine 2.2 eg.

$q = $rep->createQueryBuilder('a') 
    ->where('IDENTITY(a.member) = ?1') 
    ->andWhere('a.active = 1') 
    ->orderBy('a.id', 'DESC') 
    ->setParameter(1, $id)  
    ->getQuery(); 

produkuje następujące SQL:

SELECT m0_.id AS id0, m0_.active AS active1, m0_.update_time AS update_time2, 
     m0_.content AS content3, m0_.member_id AS member_id4 
    FROM mbr_article m0_ 
    WHERE m0_.member_id = ? AND m0_.active = 1 
    ORDER BY m0_.id DESC