【问题标题】:Symfony 3 - Doctrine wrong query structure - multi tablesSymfony 3 - 教义错误的查询结构 - 多表
【发布时间】:2017-11-07 07:43:37
【问题描述】:

我在我的 Symfony 项目中使用 Doctrine 时遇到问题。 这是我的代码:

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Doctrine\Common\Persistence\ObjectManager;
use Factory\MainBundle\Entity\Lastauction;
use Factory\MainBundle\Entity\Offers;

class AuctionListController extends Controller
{
    private $em;    
    private $qb;
    private $offer;

    public function getAuctionListAction()
    {
        $this->em = $this->getDoctrine()->getEntityManager();
        $this->qb = $this->em->createQueryBuilder();
        getAllAccount();
        for($offset=0; $offset<20000; $offset++)
        {
            $this->insertOffers();
        }   
        return new Response('Offers list generated');
    }   

    private function getAllAccount()
    {
        $this->qb->select('ac.mail')
            ->from('FactoryMainBundle:Account', 'ac');
        $result = $this->qb->getQuery()->getResult();
        $this->accounts = array_column($result, 'mail');
    }   


    private function insertOffers() 
    {
        foreach($this->offers as $id => $offer)
        {
            if($this->checkIfExsistOffer($offer))
            {
                echo $offer .'<br>';
                $offerObj = new Offers();
                $offerObj->setOffer($offer);
                $offerObj->setPage(2);
                $this->em = $this->getDoctrine()->getManager();
                $this->em->persist($offerObj);  
                if (($id % $this->batchSize) == 0) 
                {
                    $this->em->flush();
                    $this->em->clear();
                }   
            }
        }
        $this->em->flush();
        $this->em->clear();
        $this->offers = array();
    }   

    private function checkIfExsistOffer($offerUrl)
    {
        $this->qb->select('o.id')
            ->from('FactoryMainBundle:Offers', 'o')         
            ->where("o.offer=:offer")
            ->setParameter('offer', $offerUrl);
        $result = $this->qb->getQuery()->getResult();
        return (isset($result['0']['id'])) ? 1 : 0;
    }

}

我得到这个错误:

[语义错误] 第 0 行,第 134 列靠近 'o WHERE o.of':错误:'o' 已定义。

[2/2] QueryException: [Semantical Error] line 0, col 134 near 'o WHERE o.of': Error: 'o' is already defined。
[1/2] QueryException: SELECT o.id FROM FactoryMainBundle:Account ac, FactoryMainBundle:Lastauction la, FactoryMainBundle:Offers o, FactoryMainBundle:Offers o WHERE o.offer='123'

为什么 Doctrine 从其他查询中获取表?

【问题讨论】:

  • 没有任何上下文(例如,您的类映射和查询构建器的其余部分),我们真的无法告诉您。除了:为什么要在 DQL 中使用变量而不是参数并绑定它们?
  • 我更新了我的帖子。我希望现在有足够的代码来分析。
  • 您总是使用相同的查询构建器对象,只是将? select from`-tables 添加到它。
  • 是的,这就是答案:) 谢谢

标签: php mysql symfony doctrine-orm


【解决方案1】:
$this->qb->select('o.id')
        ->from('FactoryMainBundle:Offers', 'o')
        ->where("o.offer=:offer")
        ->setParameter('offer', $offerUrl);
    $result = $this->qb->getQuery()->getResult();

【讨论】:

  • 很好地建议在查询中使用参数。但是,您实际上可能想写一两句话来说明 为什么 OP 应该这样做。特别是因为它不能解决 OPs 问题。
【解决方案2】:

关于$this-&gt;qb 的代码流细分:

1) 在getAuctionListAction: $this-&gt;qb = $this-&gt;em-&gt;createQueryBuilder();

2) 在getAllAccount:

$this->qb->select('ac.mail')
         ->from('FactoryMainBundle:Account', 'ac');

3) 在checkIfExsistOffer(通过insertOffers)中,由于getAuctionListAction 中的循环,20.000 倍:

$this->qb->select('o.id')
     ->from('FactoryMainBundle:Offers', 'o')
     ->where("o.offer=:offer")
     ->setParameter('offer', $offerUrl);

长话短说:您将多个表添加到您的 $this-&gt;qb querybuilder 对象(通过 $this-&gt;qb-&gt;from(...)),这就是它们都被查询的原因。

【讨论】:

    【解决方案3】:
    private function checkIfExsistOffer($offerUrl)
    {
            $res = $this->getDoctrine()->getRepository('FactoryMainBundle:Offers')
                ->createQueryBuilder('o')
                ->select('o.id')
                ->where("o.id=:offer")
                ->setParameter('offer', 1)
                ->getQuery()
                ->getSingleResult(); //return single result 
    
            var_dump($res);die; //test
    }
    

    【讨论】:

    • 你可能真的想在你的答案中写一两句话。另外:您为什么不将其编辑到以前的答案中?在这种情况下,这可能会解决 OPs 问题(因为它正在创建一个新的 QueryBuilder),但它并没有向他解释他的代码在哪方面是错误的(所以他将来可以避免它)。
    • @ccKep,很抱歉,我的英语很差:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    相关资源
    最近更新 更多