2014-11-04 54 views
0

我做了這個SQL查詢來獲取我從DB需要的數據和它的作品正是我想要的:DQL在Doctrine2這個SQL語句多對多關係

SELECT DISTINCT ofreg.nombre as oficina 
    FROM nomencladores.oficina_regional AS ofreg 
    LEFT JOIN negocio.solicitud_usuario_oficina_regional AS solusofreg 
    ON (ofreg.id = solusofreg.oficina_regional_id) 
    JOIN nomencladores.tipo_tramite tram 
    ON (tram.id = solusofreg.tipo_tramite_id) 
    WHERE (tram.id = 1); 

因爲我的關係不會產生任何第三表額外的字段,然後我決定去上我的實體適當的註解,我們來看一看:

class TipoTramite 
{ 
    use IdentifierAutogeneratedEntityTrait; 
    use NamedEntityTrait; 
    use ActiveEntityTrait; 

    /** 
    * @ORM\ManyToMany(targetEntity="AppBundle\Entity\OficinaRegional", inversedBy="tipoTramites", cascade={"persist"}) 
    * @ORM\JoinTable(name="negocio.solicitud_usuario_oficina_regional", schema="negocio", 
    *  joinColumns={@ORM\JoinColumn(name="oficina_regional_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="tipo_tramite_id", referencedColumnName="id")} 
    *) 
    */ 
    protected $oficinaRegionals; 
} 

class OficinaRegional 
{ 
    use IdentifierAutogeneratedEntityTrait; 
    use NamedEntityTrait; 
    use ActiveEntityTrait; 

    /** 
    * @ORM\ManyToMany(targetEntity="AppBundle\Entity\TipoTramite", mappedBy="oficinaRegionals", cascade={"persist"}) 
    */ 
    protected $tipoTramites; 
} 

擁有的實體,並假定他們是正確的(糾正我,如果我錯了)我需要寫一個滿足上述SQL代碼的DQL,能否給我一些幫助來編寫這個DQL?

我一直都有它做一箇中介實體,但這種情況對我來說是全新的。作爲和另外,我知道一個解決方法,並將創建一個view在數據庫級別和寫一個實體只爲該視圖與不set方法只是get方法,因爲將是一個只讀實體,但我不知道是否是正確的道路去,我真的很想學習如何使用ManyToMany做到這一點(在我的項目中,我有很多這種類型的關係,所以我確信在不久的將來我需要這種幫助)。

UPDATE

好吧,我想保持我的這個軌道上這個問題,我做了一些測試,但沒有任何幫助的結果,這裏是我的嘗試:

第一種方法

public function filtrarOficinaRegionalPorTramite($tramite) 
{ 
    $qb = $this->getEntityManager()->createQueryBuilder(); 
    $qb 
     ->select('ofr.nombre AS oficinaRegional, ttr.nombre as tipoTramite') 
     ->from("AppBundle:OficinaRegional", "ofr") 
     ->where("ofr.activo = :activo") 
     ->leftJoin("AppBundle:TipoTramite", "ttr"); 

    $qb->setParameter('activo', TRUE); 

    if ($tramite != NULL) { 
     $qb->andWhere('ttr.id = :tramite'); 
     $qb->setParameter('tramite', $tramite); 
    } 

    echo $qb->getQuery()->getSQL(); 
    return $qb->getQuery()->getResult(); 
} 

,因爲從前面的代碼,結果SQL沒有工作是這個:

SELECT n0_.nombre AS nombre0, n1_.nombre AS nombre1 
FROM nomencladores.oficina_regional n0_ 
LEFT JOIN nomencladores.tipo_tramite n1_ 
ON (n0_.activo = ?) 

第二條本辦法

public function filtrarOficinaRegionalPorTramite($tramite) 
{ 
    $qb = $this->getEntityManager()->createQueryBuilder(); 
    $qb 
     ->select('ofr.nombre AS oficinaRegional, ttr.nombre as tipoTramite') 
     ->from("OficinaRegional ofr") 
     ->where("ofr.activo = :activo") 
     ->leftJoin('ofr.TipoTramite ttr'); 

    $qb->setParameter('tramite', $tramite); 

    if ($tramite != NULL) { 
     $qb->where('ttr.id = :tramite'); 
     $qb->setParameter('tramite', $tramite); 
    } 

    return $qb->getQuery()->getResult(); 
} 

但得到這個錯誤:

Warning: Missing argument 2 for Doctrine\ORM\QueryBuilder::from(), called in /var/www/html/project.dev/src/AppBundle/Entity/Repository/RegionalOfficeRepository.php on line 25 and defined in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php line 721

第三種方法

傳遞大量的時間試圖把事情的工作我」之後米仍然有問題,但這一次我接近修復它們。所以,這裏是我的最新的擊打,使用此代碼:

public function filtrarOficinaRegionalPorTramite($tramite) 
{ 
    $qb = $this->getEntityManager()->createQueryBuilder(); 
    $qb 
     ->select('ofr.nombre AS oficinaRegional, ttr.nombre as tipoTramite') 
     ->distinct() 
     ->from("AppBundle:OficinaRegional", "ofr") 
     ->where("ofr.activo = :activo") 
     ->leftJoin("ofr.tipoTramites", "ttr"); 

    $qb->setParameter("tramite", $tramite); 

    if ($tramite != NULL) { 
     $qb->andWhere("ttr.id = :tramite"); 
     $qb->setParameter("tramite", $tramite); 
    } 

    echo $qb->getQuery()->getSQL(); 
    return $qb->getQuery()->getResult(); 
} 

我得到這個SQL:

SELECT DISTINCT n0_.nombre AS nombre0, 
       n1_.nombre AS nombre1 
FROM nomencladores.oficina_regional n0_ 
    LEFT JOIN negocio.solicitud_usuario_oficina_regional n2_ ON n0_.id = n2_.tipo_tramite_id 
    LEFT JOIN nomencladores.tipo_tramite n1_ ON n1_.id = n2_.oficina_regional_id 
WHERE n0_.activo = ? 
     AND n1_.id = ?; 

這是沒有錯可言,但這是最終的SQL應該如何:

SELECT DISTINCT n0_.nombre AS nombre0, 
       n1_.nombre AS nombre1 
FROM nomencladores.oficina_regional n0_ 
    LEFT JOIN negocio.solicitud_usuario_oficina_regional n2_ ON n0_.id = n2_.oficina_regional_id 
    LEFT JOIN nomencladores.tipo_tramite n1_ ON n1_.id = n2_.tipo_tramite_id 
WHERE n0_.activo = TRUE 
     AND n1_.id = 1; 

我做錯了什麼?

回答

1

看起來您的加入列映射對於TipoTramite不正確,請嘗試翻轉它們。

/** 
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\OficinaRegional", inversedBy="tipoTramites", cascade={"persist"}) 
* @ORM\JoinTable(name="negocio.solicitud_usuario_oficina_regional", schema="negocio", 
*  joinColumns={@ORM\JoinColumn(name="tipo_tramite_id", referencedColumnName="id")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="oficina_regional_id", referencedColumnName="id")} 
*) 
*/ 

http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-unidirectional-with-join-table

至於問號,那些只是參數將在後面填寫。

+0

是的,這是問題,我幾分鐘前被發現,我回答了我自己的問題,但因爲你做了獎勵去給你,謝謝你的提示 – ReynierPM 2014-11-04 15:23:21

+0

哈,謝謝=)。對我也會發生很多! – Justin 2014-11-04 15:24:05