Php Doctrine2:如果不选择至少一个根实体别名,则无法通过标识变量选择实体

Php Doctrine2:如果不选择至少一个根实体别名,则无法通过标识变量选择实体,php,mysql,symfony,doctrine-orm,doctrine,Php,Mysql,Symfony,Doctrine Orm,Doctrine,我被一个原本非常简单的条令2查询所困扰。我有一个名为Category的实体,它与自身有一个单一的关系(对于父类别和子类别) 下面的查询 $q = $this->createQueryBuilder('c') ->leftJoin('c.children', 'cc') ->select('c.name as title, cc') ->where('c.parent IS NULL'); 因错误而失

我被一个原本非常简单的条令2查询所困扰。我有一个名为Category的实体,它与自身有一个单一的关系(对于父类别和子类别)

下面的查询

$q = $this->createQueryBuilder('c')
            ->leftJoin('c.children', 'cc')
            ->select('c.name as title, cc')
            ->where('c.parent IS NULL');
因错误而失败

如果不选择至少一个根实体别名,则无法通过标识变量选择实体


我真的不明白这个问题。如果我省略了
->select
部分,则查询会正常工作并给出预期结果。我已经搜索了论坛,但找不到解决方案,这很有效。有人有什么建议吗?非常感谢。

您的查询缺少一些部分。repo中的普通查询生成器如下所示

    $q = $this->getEntityManager()
        ->getRepository('MyBundle:Entity')
        ->createQueryBuilder(‌​'c')
        ->select(‌​'c')
        ->leftjoin(‌​'c.children', 'cc')
        ->addselect(‌​'cc')
        ->where(‌​'c.parent is NULL')
....
    return $q;

您的问题是,您试图从类别实体中选择一个字段,同时选择关联类别实体的整个对象。与普通SQL不同,使用QueryBuilder组件,您不能仅从要加入的表中选择实体

如果希望返回包含已联接子对象的主类别对象,可以执行
->select(array('c','cc'))
,也可以完全忽略
->select()
调用。前者将在单个查询中自动选择所需的子项。如果要访问主类别实体上的子级,则后者将需要另一个SQL查询

如果有理由希望
name
在对象中选择as
title
,则始终可以向实体添加另一个函数,该函数是用于检索名称的别名,而不必将其写入查询:

function getTitle()
{
    return $this->getName();
}

查询生成器(很可能)或实体出现问题。在这两个部分上粘贴更多代码。这是所有相关部分。查询生成器代码位于存储库中。我返回$q->getQuery()->getResult();仅此而已。repo中的普通查询生成器类似于$this->getEntityManager()->getRepository('MyBundle:Entity')->createQueryBuilder('c')
getEntityManager()
getRepository()
调用可以在您正在选择的存储库中省略。谢谢,但是当我更改select('c')时,您的查询会抛出相同的错误选择('c.name as title')。如果从我使用的实体的repo调用,则查询的第一部分是等效的。
getEntityManager()
getRepository()
如果您已经在自定义存储库中,则不需要调用。感谢您的解释。有什么解决办法吗?我的控制器将整个对象序列化为json,出于安全原因,我只想选择一些字段。当然,我可以在序列化程序中进行此选择,但是否无法仅从数据库中收集我想要的数据(即c.name和子对象)?序列化程序组件应允许您在实体上设置组,然后仅序列化这些特定组。与子对象关联的问题是可能有多个字段,否则我会说只需从另一个对象中选择单独连接的字段。您可以这样做,但这取决于JSON对象的期望。我会仔细看看序列化程序组件,组可能就是答案。@JasonRoman你说“你不能只从你要加入的表中选择…”但他不是,是吗?他是从cc(连接对象)和c.name中选择的……我修改了我的答案,以便更清楚地表明我的意思是选择一个实体。
function getTitle()
{
    return $this->getName();
}