簡體   English   中英

與Doctrine的QueryBuilder和Symfony2的許多關系

[英]ManyToMany Relationships with Doctrine's QueryBuilder and Symfony2

在我正在處理的網站上,我需要根據用戶的設置將結果限制在很多地方。 這是名為Counties的用戶的成員,並且是它自己的實體。 我把它設置成這樣:

/**
 * @ORM\Entity
 * @ORM\Table(name="county")
 */
class County
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    protected $name;

    // ... Getters and Setters
}

在我的用戶實體上,我有這樣的附件:

// ...

/**
 * @ORM\ManyToMany(targetEntity="App\Bundle\UserBundle\Entity\County")
 * @ORM\JoinTable(name="user_county_xref",
 *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="county_id", referencedColumnName="id")}
 * )
 */
protected $counties;

// ...

/**
 * Add counties
 *
 * @param \App\Bundle\UserBundle\Entity\County $counties
 * @return User
 */
public function addCountie(\App\Bundle\UserBundle\Entity\County $counties)
{
    $this->counties[] = $counties;

    return $this;
}

/**
 * Remove counties
 *
 * @param \App\Bundle\UserBundle\Entity\County $counties
 */
public function removeCountie(\App\Bundle\UserBundle\Entity\County $counties)
{
    $this->counties->removeElement($counties);
}

/**
 * Get counties
 *
 * @return \Doctrine\Common\Collections\Collection 
 */
public function getCounties()
{
    return $this->counties;
}

這一切都應該是這樣的,我可以毫無問題地將縣附加到用戶身上。

然后我有一個名為Store的第二個實體,它還附有這些County實體。 我做了相同的聲明,但將JoinTable名稱更改為JoinTable名稱,並將JoinColumn更改為使用store_id而不是user_id 就其本身而言,這很好用。 我可以將縣附加到商店。

現在,我想要做的是根據用戶的縣限制縣。 例如,如果用戶在縣A和B縣,我只想看到A縣和B縣的商店。

我無法弄清楚如何使用DQL或查詢生成器來做到這一點。 當我嘗試在Form中使用它時,這會使事情變得更糟,因為我無法使QueryBuilder語法正確,所以我無法找到一種方法來使數據限制自己。

當您以這種方式設置實體時,如何執行QueryBuilder或DQL語句?

編輯

這是我試圖復制的SQL語句,供參考:

SELECT S.* 
FROM store S 
JOIN store_county_xref SCX 
    ON SCX.store_id=S.id 
JOIN user_county_xref UCX 
    ON UCX.county_id=RCX.county_id 
WHERE UCX.user_id = 1 

部分問題是我不確定應該使用什么。 如果我添加mappedBy或inversedBy,Doctrine會抱怨索引不存在(因為它似乎在查看實體表,而不是聲明的JoinTable)。 我無法加入這樣的表格,因為Doctrine抱怨兩個實體之間沒有關聯:

SELECT s 
FROM AppStoreBundle:Store s 
JOIN AppUserBundle:County c WITH c.store = s.id

這是有道理的,因為縣里沒有“商店”成員,因為像商店和用戶這樣的東西應該有縣,而不是相反,因為縣只是一種標簽。

我甚至試過這個,認為它會起作用,但沒有多少希望:

SELECT s 
FROM AppStoreBundle:Store s 
JOIN AppUserBundle:User u WITH u.counties = s.counties

我會切換到只使用直接SQL而不是DQL / QueryBuilder,但我不確定如何在表單中運行直接SQL,這是一個主要缺點。

您可以在Doctrine文檔中找到適當聲明的示例

我在下面的代碼示例中排除了其他注釋

class County
{
    /**
     * @ManyToMany(targetEntity="User", mappedBy="counties")
     **/
    protected $users;
 }

 class User
 {
      /**
       * @ORM\ManyToMany(targetEntity="App\Bundle\UserBundle\Entity\County", inversedBy="users")
       * @ORM\JoinTable(name="user_county_xref",
       *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
       *      inverseJoinColumns={@ORM\JoinColumn(name="county_id", referencedColumnName="id")}
       * )
       */
      protected $counties;
 }

這將是正確的注釋,並且實體存儲庫中的正確查詢將是

 $queryBuilder = $this->createQueryBuilder('c');

 $queryBuilder->select(array('c', 'u'))
              ->leftJoin('c.users', 'u');

 return $queryBuilder->getQuery()->getResult();

對於另一個實體,它應該完全相同。

謝謝Thomas Potaire 好例子 ! 真的幫到了我。 請參閱下面的示例queryBuilder。 string $search, int $locale是。

$q  = $qb->select(array('a'))
                ->from(Article::class, 'a')
                ->leftJoin('a.locales', 'l')
                ->where(
                    $qb->expr()->like('a.articleName',"'%$search%'")
                )
                ->andWhere('l.id = '.$locale)
                ->orderBy('a.id', 'DESC')
                ->getQuery();
            $articles= $q->getResult();

            if ($articles==null)
                throw new \Exception('Article with key '.$search.' not found');

Article知道$locales Locale 我的項目中也有ManyToMany關系: article - > article_has_locale < - locale

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM