Doctrine DQL返回多种类型的实体 [英] Doctrine DQL returns multiple types of entities

查看:103
本文介绍了Doctrine DQL返回多种类型的实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个实体:手机订阅,手机和订阅。



HandsetSubscription的yaml是:

  App \SoBundle \\ \\ Entity\HandsetSubscription:
类型:实体
表:phones_subscription
manyToOne:
手机:
targetEntity:手机
订阅:
targetEntity :订阅
id:
id:
类型:整数
生成器:{策略:AUTO}
选项:{unsigned:true}
fields:
金额:
类型:整数
可空:false
选项:{default:0,unsigned:true}
折扣:
类型:整数
nullable:false
选项:{default:0,unsigned:true}

查询:

  SELECT hs,s,h 
FROM \App\SoBundle\Entity\HandsetSubscription hs
JOIN \App\SoBundle\Entity\Subscription s与s.id = hs.subscription
AND s.mins = 150
AND s.mb = 250
AND s.sms = 150
JOIN \App\SoBundle \Entity\Handset h with h.id = hs.handset

这些是类名的检索条目:

  App \SoBundle\Entity\HandsetSubscription 
Proxies\__CG__\App \SoBundle\Entity\Subscription
Proxies\__CG__\App\SoBundle\Entity\Handset
App \SoBundle\Entity\HandsetSubscription
Proxies\ __CG__\App\SoBundle\Entity\Handset
App \SoBundle\Entity\HandsetSubscription
Proxies\__CG__\App\SoBundle\Entity\Handset
...

我希望只收到手机订阅实体。为什么我得到订阅和手机的代理?



通过添加提取渴望手机和订阅映射,并从查询中的SELECT语句中删除手机和订阅,我将只收到手机订阅,但是我想通过fetch连接来实现,如手册中所述( http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#joins )。



更新



从上面发布的链接引用



获取加入地址:

 <?php 
$ query = $ em- > createQuery(SELECT u,a FROM User u JOIN u.address a WHERE a.city ='Berlin');
$ users = $ query-> getResult();

当Doctrine使用fetch-join来处理查询时,它会返回根级别的FROM子句中的类的结果数组。在前面的示例中,返回一个User实例数组,并将每个用户的地址取出并水化到User#地址变量中。如果您访问地址,Doctrine不需要延迟加载与另一个查询的关联。

解决方案

非常感谢veonik从#doctrine irc渠道解决这个问题。



而不是加入实体的完全限定名称,您应该加入该关联。所以查询变成:

  SELECT hs,s,h 
FROM \App\SoBundle\Entity\\ \\ HandsetSubscription hs
JOIN hs.subscription s with s.id = hs.subscription
AND s.mins = 150
AND s.mb = 250
AND s.sms = 150
JOIN hs.handset h with h.id = hs.handset


I have three entities: HandsetSubscription, Handset and Subscription.

The yaml of HandsetSubscription is:

App\SoBundle\Entity\HandsetSubscription:
type: entity
table: handset_subscription
manyToOne:
    handset:
        targetEntity: Handset
    subscription:
        targetEntity: Subscription                    
id:
    id:
        type: integer
        generator: { strategy: AUTO }
        options: { unsigned: true }
fields:
    amount:
        type: integer
        nullable: false
        options: { default: 0, unsigned: true  }
    discount:
        type: integer
        nullable: false
        options: { default: 0, unsigned: true  }

The query:

SELECT hs,s,h
      FROM  \App\SoBundle\Entity\HandsetSubscription hs                    
      JOIN  \App\SoBundle\Entity\Subscription        s with s.id    = hs.subscription 
                        AND s.mins  = 150 
                        AND s.mb    = 250 
                        AND s.sms   = 150
      JOIN  \App\SoBundle\Entity\Handset             h with h.id    = hs.handset ​

These are the class names of the entries retrieved:

App\SoBundle\Entity\HandsetSubscription
Proxies\__CG__\App\SoBundle\Entity\Subscription
Proxies\__CG__\App\SoBundle\Entity\Handset
App\SoBundle\Entity\HandsetSubscription
Proxies\__CG__\App\SoBundle\Entity\Handset
App\SoBundle\Entity\HandsetSubscription
Proxies\__CG__\App\SoBundle\Entity\Handset
…

I would expect to get only HandsetSubscription entities back. Why am I getting proxies of Subscription and Handset too?

By adding fetch eager to the handset and subscription mappings and removing handset and subscription from the SELECT statement in the query I would get only HandsetSubscription but I would like to do this through fetch joins, as stated in the manual (http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#joins).

UPDATE

Quote from the link posted above:

Fetch join of the address:

<?php
$query = $em->createQuery("SELECT u, a FROM User u JOIN u.address a WHERE a.city = 'Berlin'");
$users = $query->getResult();

When Doctrine hydrates a query with fetch-join it returns the class in the FROM clause on the root level of the result array. In the previous example an array of User instances is returned and the address of each user is fetched and hydrated into the User#address variable. If you access the address Doctrine does not need to lazy load the association with another query.

解决方案

Big thanks goes to veonik from the #doctrine irc channel for solving this.

Instead of joining with the fully qualified names of the entities you should join with the association. So the query becomes:

SELECT hs,s,h
  FROM  \App\SoBundle\Entity\HandsetSubscription hs                    
  JOIN  hs.subscription s with s.id = hs.subscription 
                    AND s.mins  = 150 
                    AND s.mb    = 250 
                    AND s.sms   = 150
  JOIN  hs.handset h with h.id = hs.handset 

这篇关于Doctrine DQL返回多种类型的实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆