1

Тема: DQL запрос в symfony (связь много ко многим)

Имею 2 сущности:
user - пользователи
stock - акции пользователя

<?php
namespace Stocker\StockBundle\Entity;

use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass="Stocker\StockBundle\Entity\Repository\UserRepository")
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    
     /**
     * @ORM\ManyToMany(targetEntity="Userstock", inversedBy="users")
     * @ORM\JoinTable(name="userstocks")
     */
    private $userstocks;

    public function __construct()
    {
        parent::__construct();
        $this->userstocks=new ArrayCollection();
    }
<?php
namespace Stocker\StockBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass="Stocker\StockBundle\Entity\Repository\UserstockRepository")
 * @ORM\Table(name="userstock")
 */
class Userstock
{
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->users = new ArrayCollection();
    }
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\Column(type="string",length=255)
     */
    protected $stockname;
    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="userstocks")
     */
    protected $users;

Я могу получить список пользователь с акциями и, наоборот, акции со списком пользователей.

А как получить список акций, которых нет у заданного пользователя?

На чистом sql это выглядит так:

SELECT us.stockname
FROM userstock us
LEFT JOIN userstocks u_s ON us.id=u_s.userstock_id AND u_s.user_id=1
WHERE u_s.user_id IS null

Но я не могу получить доступ к промежуточной таблице userstocks, т.к. для нее нет сущности. И создать сущность с привязкой к таблице userstocks тоже не могу, так как таблица уже создана.
Можно, конечно, сделать через обычный SQL, но как сделать через doctrine?
Еще можно сделать разбор на php (взять все акции и вычесть те, что есть у пользователя), но это тоже вариант так себе. Надо сразу получить готовый результат средствами DQL.

2

Re: DQL запрос в symfony (связь много ко многим)

Во-первых меня терзают смутные сомнения по поводу того, что приведенный вами sql делает именно то, что вы хотите.
Во-вторых - если вы хотите, вы можете создать промежуточную сущность несмотря на то, что "таблица уже создана". Главное правильно прописать связи.
В-третьих "в обычном SQL" и, соответственно DQL есть всякие groupby i having. Они помогут составить действительно правильный sql,ну и на основе него - dql

3 Отредактировано templton (2016-08-31 18:29:04)

Re: DQL запрос в symfony (связь много ко многим)

Hill пишет:

Во-первых меня терзают смутные сомнения по поводу того, что приведенный вами sql делает именно то, что вы хотите.
Во-вторых - если вы хотите, вы можете создать промежуточную сущность несмотря на то, что "таблица уже создана". Главное правильно прописать связи.
В-третьих "в обычном SQL" и, соответственно DQL есть всякие groupby i having. Они помогут составить действительно правильный sql,ну и на основе него - dql

Запрос правильный - проверял в PHPMyAdmin

А решение задачи оказалось более, чем простое:

//Все акции
    public function getUserAvailableStocks($userid){
        $qb=$this->createQueryBuilder('q')
                ->select('q','d')
                ->leftJoin('q.users', 'd')
                ->where('d.id!=:userid OR d.id is null')
                ->setParameter('userid', $userid);
        return $qb->getQuery()->getResult();
    }

Салам, аксакал Филл! - Привет, братан Филл!

4

Re: DQL запрос в symfony (связь много ко многим)

ааа.... я не так понял что вам нужно default/smile
думал типа "акции, у которых нет пользователей" или что-то вроде