Symfony:多对多关于孩子的where子句

时间:2017-03-27 16:22:49

标签: php symfony doctrine many-to-many

许多用户可以拥有多个项目。但我想获得特定用户拥有的特定项目列表。

我有两个实体:

用户实体:

class User
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * Many Users have many items
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Item", fetch="EAGER")
     * @ORM\JoinTable(name="users_items",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="item_id", referencedColumnName="id")}
     *      )
     */
    private $items;

}

项目实体:

class Item
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=10)
     */
    private $name;

}
然后

Doctrine创建了三个表:

items
users
users_items

我希望获得所有项目name d"铅笔"由userId 11。

拥有

我怎样才能做到这一点?

谢谢。

2 个答案:

答案 0 :(得分:1)

我希望您意识到您在用户和项目之间使用了UNIdirectional many-to-many relation。用户'知道'哪些物品属于他,但物品不知道哪些用户使用此物品。因此,您可以从数据库中检索单个用户(按用户ID),其中包含按名称过滤的项目集合。如果user-id不存在或者用户没有与过滤器匹配的项,则$ user将为NULL。在我的示例中,您可以在twig中使用if-else语句来验证用户是否为null,而不是在控制器中的异常。

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller
{
    /**
     * @Route("/someroute", name="some_route")
     */
    public function someAction()
    {
        $em = $this->getDoctrine()->getManager();

        // for this example two hardcoded parameters. $user might be NULL !
        $user = $em->getRepository('AppBundle:User')->getItemsWithNameForUser(1, 'Pencil');

        if(null === $user)
        {
            throw $this->createNotFoundException('This user does not have the selected items or the user does not exist');
        }

        return $this->render('default/index.html.twig', [
            'user' => $user
        ]);
    }
}

和UserRepository:

namespace AppBundle\Repository;

class UserRepository extends \Doctrine\ORM\EntityRepository
{
    public function getItemsWithNameForUser($userId, $itemName)
    {
        return $this->getEntityManager()->createQuery(
            'SELECT u,i FROM AppBundle:User u JOIN u.items i WHERE u.id=:id AND i.name=:name'
        )   ->setParameter('id', $userId)
            ->setParameter('name', $itemName)
            ->getOneOrNullResult();
    }

}

答案 1 :(得分:0)

我认为应该是这样的:

 mkdir c:\shadow
 mv c:\test\.hg c:\shadow\.hg
 mklink /j c:\test\.hg c:\shadow\.hg

我不确定这是否有效(语法可能不完美),但理论上应该是,你的情况下的问题是拥有方只知道关系,你想从另一方查询。