gpt4 book ai didi

symfony - 多对多关系 querybuilder 学说和 symfony2 扩展查询

转载 作者:行者123 更新时间:2023-12-04 02:24:23 25 4
gpt4 key购买 nike

我正在使用 querybuilder 应用以下查询,但不知何故,many2many 关系没有按预期工作。

$shopData = $sm->createQueryBuilder()                    
->select('v')
->from('AdminBundle:Voucher','v')
->innerJoin('v.shop', 's')
->leftJoin('AdminBundle:VoucherProgram', 'vp', \Doctrine\ORM\Query\Expr\Join::ON, 'vp.id = v.program_id')
->leftJoin('AdminBundle:shopHistory', 'sh', \Doctrine\ORM\Query\Expr\Join::ON, 'sh.shop = s.id')
->where('s.shopStatus = :shopStatus')
->setParameter('shopStatus', Shop::SHOP_ACTIVATED)
->andWhere('s.highlightedHome = :highlightedHome')
->setParameter('highlightedHome', Shop::SHOP_HIGHLIGHTED_HOME)
->andWhere('s.offers = \'voucher\'')
->setFirstResult(0)
->setMaxResults(6)
->addOrderBy('v.discount_amount', 'DESC')
->groupBy('sh.shop')
->getQuery()
->getSql();

生成的查询如下所示:
SELECT v FROM AdminBundle:Voucher v INNER JOIN v.shop s LEFT JOIN AdminBundle:VoucherPrograms vp ON vp.id = v.program_id LEFT JOIN AdminBundle:shopHistory sh ON sh.shop = s.id WHERE s.shopStatus = :shopStatus AND s.highlightedHome = :highlightedHome AND s.offers = 'voucher' GROUP BY sh.shop ORDER BY v.discount_amount DESC

如果我删除所有内容并仅保留 Many2Many 关系的内部连接,它会按预期工作。
$sm->createQueryBuilder()                    
->select('v')
->from('AdminBundle:Voucher','v')
->innerJoin('v.shop', 's');

这是生成的查询:
SELECT l0.* FROM voucher l0_ INNER JOIN shop_voucher l2_ ON l0_.id = l2_.voucher_id INNER JOIN shop l1_ ON l1_.id = l2_.shop_id;

所以我想知道为什么当我添加更多连接时系统没有选择正确的关系。

这是我具有 Many2Many 关系的主要实体:

商店.php
namespace AdminBundle\Entity;

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

/**
* Shop.
*
* @ORM\Table(name="shop")
* @ORM\Entity(repositoryClass="AdminBundle\Entity\ShopRepository")
*/
class Shop
{
const SHOP_DEACTIVATED = 0;
const SHOP_ACTIVATED = 1;
const SHOP_HIGHLIGHTED_HOME = 1;
................................
/**
* @ORM\ManyToMany(targetEntity="Voucher", inversedBy="shop")
* @ORM\JoinTable(name="shop_voucher")
*/
private $voucher;
................................

优惠券.php
namespace AdminBundle\Entity;

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

/**
* Voucher.
*
* @ORM\Table(name="voucher")
* @ORM\Entity(repositoryClass="AdminBundle\Entity\VoucherRepository")
*/
class Voucher
{
................................
/**
* @ORM\ManyToMany(targetEntity="Shop", mappedBy="voucher", cascade={"persist"})
*/
private $shop;
................................

我已经检查过有相同问题的堆栈,但我想知道我们如何扩展查询。我有我的问题的解决方案如下,但没有得到上面场景中发生的情况。
$shopDataQuery = $connection->prepare('SELECT v.* FROM voucher AS v INNER JOIN shop_voucher AS sv ON sv.voucher_id = v.id INNER JOIN shop AS s ON s.id = sv.shop_id LEFT JOIN voucher_programs AS vp ON vp.id = v.program_id LEFT JOIN shop_history AS sh ON sh.shop = s.id WHERE s.shopStatus = :shopStatus AND s.highlightedHome = :highlightedHome AND s.offers = 'voucher' GROUP BY sh.shop ORDER BY v.discount_amount DESC LIMIT 6');

更新:

这是 shopHistory.php
namespace AdminBundle\Entity;

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

/**
* shopHistory.
*
* @ORM\Table(name="shop_history")
* @ORM\Entity(repositoryClass="AdminBundle\Entity\shopHistoryRepository")
*/
class shopHistory
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @var int
* @ORM\ManyToOne(targetEntity="Shop", inversedBy="shopHistory")
* @ORM\JoinColumn(name="shop", referencedColumnName="id")
*/
private $shop;

这是 VoucherProgram.php
namespace AdminBundle\Entity;

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

/**
* VoucherProgram.
*
* @ORM\Table(name="voucher_program")
* @ORM\Entity(repositoryClass="AdminBundle\Entity\VoucherProgramRepository")
*/
class VoucherProgram
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @ORM\OneToMany(targetEntity="Voucher", mappedBy="program")
*/
private $voucher;

/**
* @ORM\OneToMany(targetEntity="Shop", mappedBy="vprogram")
*/
private $shop;

最佳答案

我认为这是因为您已将您的关系命名为与您的字段相同的名称:

SELECT v 
FROM AdminBundle:Voucher v
INNER JOIN v.shop s
LEFT JOIN AdminBundle:VoucherPrograms vp ON vp.id = v.program_id
LEFT JOIN AdminBundle:shopHistory sh ON sh.shop = s.id
WHERE s.shopStatus = :shopStatus
AND s.highlightedHome = :highlightedHome
AND s.offers = 'voucher'
GROUP BY sh.shop
ORDER BY v.discount_amount DESC

尝试在您的 中重命名店铺历史 实体字段 店铺 shop_id .

但是我没有完整的实体模型来进行测试!

如果不是这样,请尝试粘贴您的 5 个实体的代码,请...

编辑:

我使用 symfony 2.8 版本在我的本地机器上进行测试。

我已经从给定的模型中生成了实体。

我刚刚在 Voucher Entity 中添加了这个:
/**
* @ORM\ManyToOne(targetEntity="voucherProgram", inversedBy="voucher")
*/
private $program;

我有这个查询:

我的第一个查询
SELECT v 
FROM AppBundle:Voucher v
INNER JOIN v.shop s
LEFT JOIN AppBundle:voucherProgram vp WITH vp.id = v.program
LEFT JOIN AppBundle:shopHistory sh
WITH sh.shop = s.id
GROUP BY sh.shop

我的第二个 SQL 查询
SELECT v0_.id AS id0, v0_.program_id AS program_id1 
FROM voucher v0_
INNER JOIN shop_voucher s2_ ON v0_.id = s2_.voucher_id
INNER JOIN shop s1_ ON s1_.id = s2_.shop_id
LEFT JOIN voucher_program v3_ ON (v3_.id = v0_.program_id)
LEFT JOIN shop_history s4_ ON (s4_.shop = s1_.id)
GROUP BY s4_.shop
LIMIT 6
OFFSET 0

我认为生成的内容是正确的!

编辑2:

我尝试使用 symfony 标准版:
$shopData = $this->getDoctrine()
->getManager()
->createQueryBuilder()
->select('v')
->from('AppBundle:Voucher','v')
->innerJoin('v.shop', 's')
->leftJoin('AppBundle:voucherProgram', 'vp', 'WITH', 'vp.id = v.program')
->leftJoin('AppBundle:shopHistory', 'sh', 'WITH', 'sh.shop = s.id')
//->where('s.shopStatus = :shopStatus')
//->setParameter('shopStatus', Shop::SHOP_ACTIVATED)
//->andWhere('s.highlightedHome = :highlightedHome')
//->setParameter('highlightedHome', Shop::SHOP_HIGHLIGHTED_HOME)
//->andWhere('s.offers = \'voucher\'')
->setFirstResult(0)
->setMaxResults(6)
//->addOrderBy('v.discount_amount', 'DESC')
->groupBy('sh.shop')
->getQuery()
->getDql();

我的 composer.json 是:
"php": ">=5.3.9",
"symfony/symfony": "2.8.*",
"doctrine/orm": "^2.4.8",
"doctrine/doctrine-bundle": "~1.4",
"symfony/swiftmailer-bundle": "~2.3",
"symfony/monolog-bundle": "~2.4",
"sensio/distribution-bundle": "~5.0",
"sensio/framework-extra-bundle": "^3.0.2",
"incenteev/composer-parameter-handler": "~2.0"

我的实体:

店铺
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* Shop
*
* @ORM\Table(name="shop")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ShopRepository")
*/
class Shop
{
const SHOP_DEACTIVATED = 0;
const SHOP_ACTIVATED = 1;
const SHOP_HIGHLIGHTED_HOME = 1;

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


/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* @ORM\ManyToMany(targetEntity="Voucher", inversedBy="shop")
* @ORM\JoinTable(name="shop_voucher")
*/
private $voucher;
}

店铺历史
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* shopHistory
*
* @ORM\Table(name="shop_history")
* @ORM\Entity(repositoryClass="AppBundle\Repository\shopHistoryRepository")
*/
class shopHistory
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;


/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* @var int
* @ORM\ManyToOne(targetEntity="Shop", inversedBy="shopHistory")
* @ORM\JoinColumn(name="shop", referencedColumnName="id")
*/
private $shop;
}

代金券
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* Voucher
*
* @ORM\Table(name="voucher")
* @ORM\Entity(repositoryClass="AppBundle\Repository\VoucherRepository")
*/
class Voucher
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;


/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* @ORM\ManyToMany(targetEntity="Shop", mappedBy="voucher", cascade={"persist"})
*/
private $shop;

/**
* @ORM\ManyToOne(targetEntity="voucherProgram", inversedBy="voucher")
*/
private $program;
}

优惠券计划
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* voucherProgram
*
* @ORM\Table(name="voucher_program")
* @ORM\Entity(repositoryClass="AppBundle\Repository\voucherProgramRepository")
*/
class voucherProgram
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @ORM\OneToMany(targetEntity="Voucher", mappedBy="program")
*/
private $voucher;

/**
* @ORM\OneToMany(targetEntity="Shop", mappedBy="vprogram")
*/
private $shop;

/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
}

关于symfony - 多对多关系 querybuilder 学说和 symfony2 扩展查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39547112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com