关于学说:查询生成器/DQL 不能与 INNER JOIN 一起使用 – 语法问题

Query Builder / DQL not working with INNER JOIN - Syntax Issue

我知道我在这里有语法问题,但我无法弄清楚。我正在尝试对 5 个表进行 SELECT 和 INNER JOIN,但 Symfony 抱怨在定义之前使用了 JOIN 中的实体。

实际错误如下:[Semantical Error] line 0, col 121 near 'I ON C.id = ': Error: Identification Variable MySiteBundle:Items used in join path expression but was not defined before.

这是 PHP 代码。

注意:我已将此查询缩短为两列、两个表和一个连接,以保持问题简单并表明我的观点。实际查询要长得多并且产生相同的错误。

1
2
3
4
5
6
$em = $this->getDoctrine()->getEntityManager();
$query = $em->createQuery(
    'select C.name as CName, I.id as IId
    FROM MySiteBundle:Categories C
    INNER JOIN MySiteBundle:Items I ON C.id = I.category_id');
$result = $query->getResult();

更新

正如建议的那样,我已经取消了 DQL 代码并正在使用查询生成器代码。我收到了一个非常类似的错误,上面写着 'Categories c': Error: Class 'Categories' is not defined。我的 QB 代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
$em = $this->getDoctrine()->getEntityManager();
$qb = $em->createQueryBuilder()
        ->select('c.name, i.id, i.image, i.name, i.description, m.id, m.quantity, m.value, m.qty_received, m.custom_image, m.custom_name, m.custom_description, u.user1fname, u.user1lname, u.user2fname, u.user2lname')
        ->from('Categories', 'c')
        ->innerJoin('Items', 'i', 'ON', 'c.id = i.category_id')
        ->innerJoin('MemberItems', 'm', 'ON', 'i.id = m.item_id')
        ->innerJoin('User', 'u', 'ON', 'm.memberinfo_id = u.id')
        ->where('u.id = ?', $slug)
        ->orderBy('c.id', 'ASC')
        ->getQuery();

$memberItems = $qb->getResult();

有什么建议吗?


Louis 在我打字时发帖。哦,好吧。

DQL 会根据您的关联为您处理加入详细信息。一般情况下,只需要拼出FROM类名即可。类似于:

1
2
3
'select C.name as CName, I.id as IId
FROM MySiteBundle:Categories C
INNER JOIN C.items');

并最终使用查询生成器。

================================================ ===============================

这是在 Symfony 2 中使用查询生成器的示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public function getAccounts($params = array())
{
    // Build query
    $em = $this->getEntityManager();
    $qb = $em->createQueryBuilder();

    $qb->addSelect('account');
    $qb->addSelect('accountPerson');
    $qb->addSelect('person');
    $qb->addSelect('registeredPerson');
    $qb->addSelect('projectPerson');

    $qb->from('ZaysoCoreBundle:Account','account');

    $qb->leftJoin('account.accountPersons',  'accountPerson');
    $qb->leftJoin('accountPerson.person',    'person');
    $qb->leftJoin('person.registeredPersons','registeredPerson');
    $qb->leftJoin('person.projects',         'projectPerson');
    $qb->leftJoin('projectPerson.project',   'project');

    if (isset($params['accountId']))
    {
        $qb->andWhere($qb->expr()->in('account.id',$params['accountId']));
    }
    if (isset($params['projectId']))
    {
        $qb->andWhere($qb->expr()->in('project.id',$params['projectId']));
    }
    if (isset($params['aysoid']))
    {
        $qb->andWhere($qb->expr()->eq('registeredPerson.regKey',$qb->expr()->literal($params['aysoid'])));
    }
    $query = $qb->getQuery();

  //die('DQL ' . $query->getSQL());
    return $query->getResult();
}


DQL 不使用这样的连接。它们有点简化。但是我也发现它们的文档不足。

1
2
3
4
5
6
    $em = $this->getDoctrine()->getEntityManager();
    $query = $em->createQuery(
        'select C.name as CName, I.id as IId
        FROM MySiteBundle:Categories C
        INNER JOIN C.items I');
    $result = $query->getResult();

实际使用的关系取决于您的模型。

我通常使用查询生成器。

1
2
3
4
5
6
7
8
    $em = $this->getEntityManager();
    $request = $em->getRepository('MySiteBundle:Categories');

    $qb = $request->createQueryBuilder('C');
    $query = $qb
        ->select('C.name, I.id')
        ->innerJoin('C.items', 'I')
        ->getQuery();


您可能需要检查注释或 yml 文件,以确保您的映射设置正确,适用于 OneToMany、ManyToMany 和 ManyToOne。

在您的 MemberItems Controller 或 MemberItems Repository 中输入:

1
2
3
4
5
6
7
8
9
10
11
12
13
$em = $this->getDoctrine()->getEntityManager();
$qb = $em->createQueryBuilder()
    ->select('c.name, i.id, i.image, i.name, i.description, m.id, m.quantity, m.value, m.qty_received, m.custom_image, m.custom_name, m.custom_description, u.user1fname, u.user1lname, u.user2fname, u.user2lname')
    ->from('m')
    ->innerJoin('m.memberinfo_id', 'u')
    ->innerJoin('m.item_id', 'i')
    ->innerJoin('i.category_id', 'c')
    ->where(
    ->where('u.id = ?', $slug)
    ->orderBy('c.id', 'ASC')
    ->getQuery();

$memberItems = $qb->getResult();