2012-02-03 7 views
7

documentazione afferma:Come specificare diverse condizioni di join per 1: 1 rapporto in Dottrina 2

class Cart 
{ 
    // ... 

    /** 
    * @OneToOne(targetEntity="Customer", inversedBy="cart") 
    * @JoinColumn(name="customer_id", referencedColumnName="id") 
    */ 
    private $customer; 

    // ... 
} 

Questa annotazione rappresenta tale sql:

JOIN Customer c ON c.id = cart.customer_id 

E il problema è che ho bisogno di aggiungere ulteriori confronto, come:

JOIN Customer c ON c.id = cart.customer_id AND c.anotherField = <constant> 

Qualche soluzione per questo?

UPD:

la vera condizione supplementare ho bisogno per ora è <const> BETWEEN c.f1 AND c.f2

+0

Hai provato di specificare secondo unirsi colonna con 'columnDefinition =" enum ('YOUR_CONSTANT') ")'? – jkucharovic

+0

È possibile utilizzare queryBuilder quando si effettua la query? – CappY

+0

In realtà, la seconda condizione è un po 'più difficile - ho pensato che non fosse importante per la soluzione * generale *. Per ora ho bisogno di 'E TRA c.f1 E c.f2' – zerkms

risposta

0

è possibile utilizzare la parola chiave WITH per specificare ulteriori condizioni di join, come si può vedere in alcune delle examples.

credo che questo dovrebbe farti andare:

SELECT l, c FROM location 
INNER JOIN Customer c 
WITH CURRENT_TIMESTAMP() BETWEEN c.f1 AND c.f2 
WHERE CURRENT_TIMESTAMP() BETWEEN l.f1 AND l.f2 

ho rimosso la clausola ON perché penso che ci sia alcun bisogno di specificare esplicitamente il ON campi di unirsi a meno che essi non sono la "standard" quelli (id di ogni entità)

notare anche la chiamata a CURRENT_TIMESTAMP() che si traduce in NOW() di MySQL. controlla un elenco di altre funzioni ed espressioni aggregate piuttosto utili here

+2

In realtà non risponde alla domanda. Diciamo che volevi solo record attivi, puoi esprimerlo con la notazione? O per favore spiega come usare quel blob di DQL per popolare la proprietà di un'entità. – ficuscr

0

Non sembra esserci alcuna soluzione al tuo problema che Doctrine possa fare in modo auto magicamente.

Poiché @ficuscr ti ha già fornito una soluzione per le query, c'è solo un'altra cosa da gestire: controlla i criteri aggiuntivi e restituisci l'istanza del cliente nel tuo getter in caso di successo e NULL in caso di mancato rispetto dei criteri aggiuntivi.

class Cart 
{ 
    const VALUE = '<some_constant_value>'; 
    /** 
    * @OneToOne(targetEntity="Customer", inversedBy="cart") 
    * @JoinColumn(name="customer_id", referencedColumnName="id") 
    */ 
    private $customer; 

    // ... 

    /** 
    * @return Customer|null 
    */ 
    public function getCustomer() 
    { 
     if ($this->customer->getField1() <= self::VALUE 
      && $this->customer->getField2() >= self::VALUE 
     ) { 
      return $this->customer; 
     } 

     return null; 
    } 
} 

Se questo fosse un uno-a-molti relazione, Collection Filtering API (aka Criteri) potrebbe essere usato per filtrare la collezione creata dalle mappature:

use Doctrine\Common\Collections\Criteria; 

class Cart 
{ 
    const VALUE = '<some_constant_value>'; 
    /** 
    * @OneToMany(targetEntity="Customer", mappedBy="cart") 
    */ 
    private $customers; 

    // ... 

    /** 
    * @return Customer[]|ArrayCollection 
    */ 
    public function getCustomers() 
    { 
     $expr = Criteria::expr(); 
     $criteria = Criteria::create() 
      ->where($expr->andX(
       $expr->lte('field1', self::VALUE), 
       $expr->gte('field2', self::VALUE) 
      )); 

     return $this->patientProblems->matching($criteria); 
    } 
}