given the two following intities:
<?php
/**
* User
* @ORM\Entity()
*/
class User implements AdvancedUserInterface, \Serializable, EncoderAwareInterface
{
/**
* @var Vip
* @ORM\OneToOne(targetEntity="Vip", mappedBy="user", fetch="EAGER")
*/
protected $vip;
// …
<?php
/**
* Vip
* @ORM\Entity()
*/
class Vip
{
/**
* @ORM\id @ORM\OneToOne(targetEntity="User", inversedBy="vip", fetch="EAGER")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
*/
protected $user;
// …
SHORT :
How can I do this SQL in DQL given above entities:
SELECT u.firstName, v.foo FROM User join Vip v ON v.user_id = u.id
In other words how can I retrieve 10 first users ( with their VIP infos if it exists), using DQL join
in such a way that only one SQL query will be generated by Doctrine. Is that possible ?
Long story:
The owning side is the Vip
entity because it holds the reference/foreign key to a User underneath in the database.
I am trying to retrieve all User
with their Vip
datas.
Using the knplabs/knp-paginator-bundle, I first set up a simple query:
$dql = "SELECT u, p FROM AppBundle:User u;
In spite of enforcing the fetch attribute as « EAGER », Vip
infos where not part of the initial query. As a consequence, calling getter getVip()
on each iteration from inside the twig for in
loop like
{% for user in pagination %}
{% if user.getVip() %}
<span class="label label-warning">V.I.P</span>
{% endif %}
{{% endfor %}}
.. caused a query to be issued on each iteration !
The Symfony dev bar shows 6 queries:
DQL documentation and says that one can use JOIN keyword. So my query became:
$dql = "SELECT u, v FROM AppBundle:User u JOIN u.vip v
;
But now I get this error:
Warning: spl_object_hash() expects parameter 1 to be object, null given
Here I'm stuck, wondering how I could fetch Vip
datas (or null) along with User
datas, in a single query.
答案 0 :(得分:1)
换句话说,如何检索10个第一个用户(使用他们的VIP) 如果它存在的信息),使用DQL连接只有一个SQL的方式 查询将由Doctrine生成。这可能吗?
您应该使用select子句初始化所有相关实体,以避免在访问相关对象时出现其他查询。
$repository = $em->getRepository(User::class);
$users = $repository->createQueryBuilder('u')
->addSelect('v') // Initialize Vip's
->join('u.vip', 'v')
->getQuery()
->setMaxResults(10)
->getResult();