Doctrine2:[语义错误]如果不选择至少一个根实体别名,则无法通过标识变量选择实体

时间:2016-02-28 16:35:33

标签: symfony doctrine-orm zend-framework2 query-builder doctrine-query

这是我对查询构建器的查询,它完美地工作,带来了用户表和模块表的所有结果,这些结果具有多对多关联:

public function getUser($id){
    $qb = $this->getEm()->createQueryBuilder()
    ->select('u', 'm')
    ->from('Adm\Entity\User', 'u')
    ->join('u.modules', 'm')
    ->where('u.id = ?1')
    ->setParameters(array(1 => $id));
    $result = $qb->getQuery()->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
    return $result;
}

但是当我尝试从这样的用户中选择特定字段时:

public function getUser($id){
    $qb = $this->getEm()->createQueryBuilder()
    ->select('u.id, u.name, u.email', 'm')
    ->from('Adm\Entity\User', 'u')
    ->join('u.modules', 'm')
    ->where('u.id = ?1')
    ->setParameters(array(1 => $id));
    $result = $qb->getQuery()->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
    return $result;
}

Doctrine抛出错误:

[Semantical Error] line 0, col -1 near 'SELECT u.id,': Error: Cannot select entity through identification variables without choosing at least one root entity alias.

我想知道如何做到这一点,从实体而不是所有字段中选择特定字段。

1 个答案:

答案 0 :(得分:4)

第二个查询的问题是您尝试返回关联的modules对象而不是User对象。学说不喜欢这样,并且不以这种方式运作。我知道你试图给阵列加水,但如果你没有,这就是你的第一个查询试图返回的内容:

User object {
    ...,
    $modules -> array of Module objects
}

因此,您将返回单个User对象,然后该User类的$modules成员将成为所有关联模块对象的数组。即使您选择u, m,Doctrine仍然希望返回该对象,因为m只是u上的关联。仅仅因为你想要对数组进行水合并不会改变Doctrine想要开始选择数据的方式。

你的第二个例子 - Doctrine不知道如何归还。通过单独选择“用户”字段,您不再返回User对象,而是返回User值数组。那么,它甚至可以在哪里返回相关模块?返回这种格式是没有意义的:

[
    user id,
    user name,
    user email,
    [ array of Module objects ]
]

这与多对多关联更为棘手。真正的问题是,你试图用你的第一个查询发现第二个查询无法接受的第二个查询是什么?如果它的性能,你可能没有获得第二个查询太多。如果它只是返回特定列,那么您也应该指定那些m.列。