gpt4 book ai didi

php - DQL Query Doctrine 将连接元素 OrderBy 子句放在另一个元素的接合条件的子查询中

转载 作者:行者123 更新时间:2023-11-30 21:47:44 25 4
gpt4 key购买 nike

这是我的情况:

我有一个实体用户,有几个连接的实体集合:

class User
{
private $id;

/**
* @var UserData
* @ORM\OneToMany(targetEntity="UserData", mappedBy="user")
*/
private $userDatas;

/**
* @var ServiceAccess
* @ORM\OneToMany(targetEntity="ServiceAccess", mappedBy="user")
*/
private $serviceAccesses;

...

}

ServiceAccess 在 Offers 上也有一个 OneToMany 连接,在其 level 字段上有一个 OrderBy 指令到 Doctrine ORM:

class ServiceAccess
{
private $id;

/**
* Offers
* @ORM\OneToMany(targetEntity="Offer",
* mappedBy="access",
* cascade={"persist","remove","refresh"})
* @ORM\OrderBy({"level" = "DESC"})
*/
private $offers;

/**
* @ORM\ManyToOne(
* targetEntity="User"
* )
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
*/
private $user;
...
}

我的优惠类别:

class Offer
{

private $id;

/**
* The user access
*
* @var ServiceAccess
* @ORM\ManyToOne(targetEntity="Fitnext\ServiceAccessBundle\Domain\Entity\UserServiceAccess", inversedBy="offers")
* @ORM\JoinColumn(name="access_id", referencedColumnName="id", nullable=false)
*/
private $access;

/**
* @ORM\Column(name="level", type="integer", nullable=false, options={"default"=0})
*/
private $level;
...
}

我正在实现 DQL 查询以获取具有多个依赖项的用户,包括其 UserDatas、ServiceAccesses 和 ServiceAccesses.offers。

这里的主要技巧是User.userDatas 接合点 的条件:UserData 有一个name 和一个createdAt 字段,并且可以包含多个具有相同name 的行。我的目标是查询每个定义的 name 组的最新行。为此,我使用了一个子查询(这是在 Stackoverflow 上发送给我的 :) ),它工作得很好。

另外,我还有几个经典的接合点,其中一个在 User.serviceAccesses 上,然后是 一个在 ServiceAccesses.offers 上,当与 UserData 子查询 结合使用时,这会导致我出现问题。 ..

这是我的查询生成器:

// First I define the subquery for the UserDatas juncture condition
$queryDatas = $this->_em->createQueryBuilder()
->select('a')
->from('UserData', 'a')
->leftJoin( 'UserData', 'b', 'WITH', 'a.name = b.name AND a.createdAt < b.createdAt' )
->where( 'b.createdAt IS NULL' )
->andWhere('a.name IN (:names)')
->andWhere('a.user = u')
->orderBy( 'a.createdAt', 'DESC' )
->getDQL();

// Notice the orderBy clause here, which is part of the trick in order to get the latest registration of each named data group, and which is also part of the issue...

// And here is the main QueryBuilder
$this->createQueryBuilder('u')

->where('u.id = :id')
->setParameter('id', $id)

// UserDatas
->leftJoin('u.userDatas', 'd', 'WITH', 'd IN ('. $queryDatas .')')
->addSelect('d')
->setParameter('names', ['height', 'weight'])

// ServiceAccess
->leftJoin('u.serviceAccesses', 'svacc', 'WITH', 'svacc.activated = 1 AND svacc.type = :type' )
->setParameter('type','default')
->addSelect('svacc')

// ServiceAccessOffers
->leftJoin('svacc.offers', 'offers', 'WITH', 'offers.activated = 1' )
->addSelect('offers')
...

这会返回一个 Doctrine\DBAL\Exception\InvalidFieldNameException:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'u7_.level' in 'order clause'

这是导致问题的生成的 SQL 代码部分:

   FROM users u0_
LEFT JOIN user_data e1_ ON u0_.id = e1_.user_id
AND (e1_.id IN (
SELECT e8_.id
FROM user_data e8_
LEFT JOIN user_data e9_ ON (e8_.name = e9_.name AND e8_.created_at < e9_.created_at)
WHERE e9_.created_at IS NULL AND e8_.name IN ('height', 'weight')
AND e8_.user_id = u0_.id
ORDER BY e8_.created_at DESC, u7_.level DESC
)
)
LEFT JOIN service_access u6_ ON u0_.id = u6_.user_id AND (u6_.activated = 1 AND u6_.type = 'default')
LEFT JOIN offer u7_ ON u6_.id = u7_.access_id AND (u7_.activated = 1)

Doctrine 采用 Access.offers 属性(orderBy 级别 DESC)中定义的 OrderBy 子句,并将其添加到子查询 orderBy!当然,它不知道报价表及其级别字段,因为它们不在子查询范围内!

它的工作原理就好像 Doctrine 将 orderBy 添加到它在查询中找到的唯一/第一个 OrderBy,在这种情况下这是行不通的..

IMO 这是一个 Doctrine 错误。

我目前在“symfony/symfony”下:“^3.4”, “学说/规范”:“2.5.12”,。

有人知道吗?我是第一个遇到这个问题的人吗?

非常感谢。

最佳答案

好吧,我现在觉得有点菜鸟..但我解决了这个问题..我只是重新组织了我的 QueryBuilder 方法顺序,将 Offers 接合点放在另一个接合点之前,以便它在正确的位置生成第一个 orderBy 子句,而不是将它添加到子查询中创建的子句中。

有效。

仍然认为这有点奇怪,因为 QueryBuilder 方法应该不管它们被调用的顺序如何工作..

关于php - DQL Query Doctrine 将连接元素 OrderBy 子句放在另一个元素的接合条件的子查询中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48684549/

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