2013-07-02 145 views
3

在我正在处理的网站上,我需要根据用户的设置将结果限制在不少位置。这是用户名为Counties的成员,并且是它自己的权利实体。我有它设置如下:ManyToMany与Doctrine的QueryBuilder和Symfony2的关系

/** 
* @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; 
} 

这所有的作品像它应该的,我可以附加县用户没有问题。

然后我有第二个实体称为商店也有这些县实体附加到它。我做了同样的声明,但将JoinTable的名称更改为不同的内容,并将JoinColumn更改为使用store_id而不是user_id。就其本身而言,这工作得很好。我可以将县附加到商店。

现在,我想要做的是限制县根据用户的县。例如,如果用户在县A和县B,我只想看到县A和县B的商店。

我无法弄清楚如何使用DQL或查询生成器来做到这一点。这使事情变得更糟,当我试图在表单中使用它,并且因为我无法获得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)。我不能加入这样的表,因为教义抱怨说有两个实体之间不存在关联关系:

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 

我会切换到只使用,而不是DQL/QueryBuilder的直接的SQL,但我不知道如何在表单中直接运行SQL,这是一个主要的缺点。

+0

你应该用你的实体选项的mappedBy和inversedBy因而可以存在一个拥有方。另外,你是否尝试过任何DQL语法?你能分享一些吗? –

+0

用我想要复制的SQL更新了问题,以及我试过的一些示例DQL – dragonmantank

回答

2

您可以找到Doctrine documentation

适当声明的一个例子,我已经排除的代码示例的其他注释下面

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(); 

它应该是完全相同的另一个实体。

+0

因此,如果我正确理解这一点,那么County实体将需要为每个引用它的对象都有一个成员?因此,如果我稍后添加一个市场实体,并且有一个与之相关的县,那么我需要向该县实体添加一个“市场”成员? – dragonmantank

+0

是的,这就是学说如何加入和补充实体之间的联系。此外,'mappedBy'和'inversedBy'的值是关系对面成员的名字。 –

0

谢谢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知道Locale$locales。我在我的项目还多对多关系:文章 - > article_has_locale < - 区域

相关问题