Symfony \ Doctrine createQueryBuilder()从OneToMany关系中选择“不在”

我有三个实体:奖杯|比赛|季节

为一个赛季的一个奖杯创建了一个竞赛(您不能同时使用“季节+奖杯”的组合来进行两个竞赛)。

竞争与Trophy的ManyToOne关系,与Season的ManyToOne关系。

奖杯和季节没有直接关系。

我想在页面上显示两个下拉菜单,其中第二个下拉菜单的内容取决于第一个下拉菜单的值: 第一个下拉列表允许选择奖杯类型(这是Trophy实体的属性),第二个下拉列表必须列出所选奖杯类型“仍可用”的季节(意思是“列出所有对此奖杯没有竞争的季节)类型”)

我几乎可以工作了(Formtype,ajax等中的侦听器),我在SeasonRepository中创建了一个特定的函数allWithoutThisCompetitionType()。每次用户都在下拉菜单中选择一个新值时会正确调用该函数...我对SQL和dql一无所知,所以我在努力为查询找到正确的公式。我已经尝试过使用notin(),“ sub”或“ nested”查询...我绝对不知道我在做什么...

我该怎么做? :

$qb = $em->getRepository(\App\Entity\Seasonmanager\Season::class)->createQueryBuilder('s')
            ->where('s.competitions.trophy != :trophy')
    ->setParameter('trophy',$trophy);

=这是这个奖杯尚未建立任何比赛的所有季节

谢谢您的帮助。

奖杯实体:

/**
 * @ORM\Entity(repositoryClass="App\Repository\Seasonmanager\TrophyRepository")
 */
class Trophy
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string",length=255)
     */
    private $uniqueid;


 // other properties here...    
//////////////////////////////////////////////////////////////////////////////////

//// LIAISONS VERS D'AUTRES ENTITY ////

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Seasonmanager\Competition",mappedBy="trophy",orphanRemoval=true)
     */
    private $competitions;

竞争实体:

/**
 * @ORM\Entity(repositoryClass="App\Repository\Seasonmanager\CompetitionRepository")
 * @UniqueEntity(
 *    fields={"trophy","season"},*    errorPath="trophy",*    message="Une compétition existe déjà pour ce trophée et cette saison"
 * )
 */
class Competition
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

// other properties here...

//////////////////////////////////////////////////////////////////////////////////

//// LIAISONS VERS D'AUTRES ENTITY ////

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Seasonmanager\Trophy",inversedBy="competitions")
     * @ORM\JoinColumn(nullable=false)
     */
    private $trophy;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Seasonmanager\Season",inversedBy="competitions")
     * @ORM\JoinColumn(nullable=false)
     */
    private $season;

季节实体:

/**
 * @ORM\Entity(repositoryClass="App\Repository\Seasonmanager\SeasonRepository")
 * @UniqueEntity("yearin")
 */
class Season
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="integer",length=4)
     */
    private $yearout;

    /**
     * @ORM\Column(type="string",length=8)
     */
    private $uniqueid;

// other properties here...

//////////////////////////////////////////////////////////////////////////////////

//// LIAISONS VERS D'AUTRES ENTITY ////

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Seasonmanager\Competition",mappedBy="season",orphanRemoval=true)
     */
    private $competitions;

我试图在其中添加查询的SeasonRepository:

namespace App\Repository\Seasonmanager;

use App\Entity\Seasonmanager\Season;
use App\Entity\Seasonmanager\Trophy;
use App\Entity\Seasonmanager\Competition;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;

/**
 * @method Season|null find($id,$lockMode = null,$lockVersion = null)
 * @method Season|null findOneBy(array $criteria,array $orderBy = null)
 * @method Season[]    findAll()
 * @method Season[]    findBy(array $criteria,array $orderBy = null,$limit = null,$offset = null)
 */
class SeasonRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry,Season::class);
    }

    public function allWithoutThisCompetitionType($type): array
    {
        $em = $this->getEntityManager();
        $trophys = $em
            ->getRepository(Trophy::class)
            ->findBy(['uniqueid' => $type],['id'=>'DESC'])
        ;
        $trophy = reset($trophys);

        $qb = $em->getRepository(\App\Entity\Seasonmanager\Season::class)->createQueryBuilder('s')
            ->where('s.competitions.trophy',$trophy);
        $query = $qb->getQuery();
        $result = $query->getResult();
        $donnees = $result;
        return $donnees;

    }
gengwenshuang 回答:Symfony \ Doctrine createQueryBuilder()从OneToMany关系中选择“不在”

这是查询,但是,我不确定100%是否会满足您的需求。
如果有问题,请在评论中告诉我,我将编辑答案。

public function allWithoutThisCompetitionType($trophy) {
    // Split init from the rest of the query in case you need to use `$qb->expr()`
    $qb=$this->createQueryBuilder("season");

    $qb->leftJoin("season.competition","competition") // Join competition
       ->join("competition.trophy","trophy") // Join Trophy
       ->andWhere($qb->expr()->orX( // Or (either one of the following satements)
            $qb->expr()->isNull("competition.id"),$qb->expr()->notIn("trophy.uniqueid",":trophy")))
       ->setParameter("trophy",$trophy);

    return $qb->getQuery()->getResult();
}
本文链接:https://www.f2er.com/3165270.html

大家都在问