简体   繁体   中英

Doctrine Native SQL many-to-many query

I have a many-to-many relationship between Students and Programs with tables student , program , and student_program in my database.

I'm trying to join the two entities and perform some custom queries that require subqueries. This means that the Doctrine QueryBuilder cannot work because it does not support subqueries.

Instead, I'm trying the NativeSQL function and am making decent progress. However, when I try to SELECT something from the Program entity, I get the error Notice: Undefined index: Bundle\\Entity\\Program in vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php line 180 .

    $mapping = new \Doctrine\ORM\Query\ResultSetMappingBuilder($em);
    $mapping->addRootEntityFromClassMetadata('Student', 's');
    $mapping->addJoinedEntityFromClassMetadata('Program', 'p', 's', 'programs', array('id' => 'program_id'));
    // Query based on form 
    $sql = 'SELECT s.id, s.last_name, p.name <---- problem when this is added
            FROM student s
            JOIN program p
            ';

    $query = $em->createNativeQuery($sql, $mapping);

    $students = $query->getResult();

Not a direct answer but doctrine 2 does indeed support sub queries. Just create a query then feed the dql into a where class. This example is somewhat verbose but it works just fine:

public function queryGames($search)
{
    // Pull params
    $ages    = $this->getValues($search,'ages');
    $genders = $this->getValues($search,'genders');
    $regions = $this->getValues($search,'regions');

    $sortBy  = $this->getValues($search,'sortBy',1);
    $date1   = $this->getValues($search,'date1');
    $date2   = $this->getValues($search,'date2');
    $time1   = $this->getValues($search,'time1');
    $time2   = $this->getValues($search,'time2');

    $projectId = $this->getValues($search,'projectId');

    // Build query
    $em = $this->getEntityManager();
    $qbGameId = $em->createQueryBuilder(); // ### SUB QUERY ###

    $qbGameId->addSelect('distinct gameGameId.id');

    $qbGameId->from('ZaysoCoreBundle:Event','gameGameId');

    $qbGameId->leftJoin('gameGameId.teams',   'gameTeamGameId');
    $qbGameId->leftJoin('gameTeamGameId.team','teamGameId');

    if ($projectId) $qbGameId->andWhere($qbGameId->expr()->in('gameGameId.projectId',$projectId));

    if ($date1) $qbGameId->andWhere($qbGameId->expr()->gte('gameGameId.date',$date1));
    if ($date2) $qbGameId->andWhere($qbGameId->expr()->lte('gameGameId.date',$date2));

    if ($time1) $qbGameId->andWhere($qbGameId->expr()->gte('gameGameId.time',$time1));
    if ($time2) $qbGameId->andWhere($qbGameId->expr()->lte('gameGameId.time',$time2));

    if ($ages)    $qbGameId->andWhere($qbGameId->expr()->in('teamGameId.age',   $ages));
    if ($genders) $qbGameId->andWhere($qbGameId->expr()->in('teamGameId.gender',$genders));

    if ($regions) 
    {
        // $regions[] = NULL;
        // $qbGameId->andWhere($qbGameId->expr()->in('teamGameId.org',   $regions));

        $qbGameId->andWhere($qbGameId->expr()->orX(
            $qbGameId->expr()->in('teamGameId.org',$regions),
            $qbGameId->expr()->isNull('teamGameId.org')
        ));

    }
    //$gameIds = $qbGameId->getQuery()->getArrayResult();
    //Debug::dump($gameIds);die();
    //return $gameIds;

    // Games
    $qbGames = $em->createQueryBuilder();

    $qbGames->addSelect('game');
    $qbGames->addSelect('gameTeam');
    $qbGames->addSelect('team');
    $qbGames->addSelect('field');

    $qbGames->addSelect('gamePerson');
    $qbGames->addSelect('person');

    $qbGames->from('ZaysoCoreBundle:Event','game');

    $qbGames->leftJoin('game.teams',   'gameTeam');
    $qbGames->leftJoin('game.persons', 'gamePerson');
    $qbGames->leftJoin('game.field',   'field');

    $qbGames->leftJoin('gameTeam.team',     'team');
    $qbGames->leftJoin('gamePerson.person', 'person');

    $qbGames->andWhere($qbGames->expr()->in('game.id',$qbGameId->getDQL())); // ### THE TRICK ###

    switch($sortBy)
    {
        case 1:
            $qbGames->addOrderBy('game.date');
            $qbGames->addOrderBy('game.time');
            $qbGames->addOrderBy('field.key1');
            break;
        case 2:
            $qbGames->addOrderBy('game.date');
            $qbGames->addOrderBy('field.key1');
            $qbGames->addOrderBy('game.time');
            break;
        case 3:
            $qbGames->addOrderBy('game.date');
            $qbGames->addOrderBy('team.age');
            $qbGames->addOrderBy('game.time');
            $qbGames->addOrderBy('field.key1');
            break;
    }

    // Always get an array even if no records found
    $query = $qbGames->getQuery();
    $items = $query->getResult();

    return $items;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM