Doctrine 查询生成器/DQL无法使用内部联接-语法问题

Doctrine 查询生成器/DQL无法使用内部联接-语法问题,doctrine,symfony,inner-join,dql,query-builder,Doctrine,Symfony,Inner Join,Dql,Query Builder,我知道我这里有一个语法问题,但我想不出来。我试图对5个表进行选择和内部联接,但Symfony抱怨联接中的实体在定义之前就被使用了 实际错误如下:[Semantical error]第0行,靠近'I ON C.id='的第121列:错误:标识变量MySiteBundle:在联接路径表达式中使用的项,但之前未定义。 下面是PHP代码 注意:我已将此查询缩短为两列、两个表和一个联接,以保持问题的简单性并说明我的观点。实际的查询要长得多,并且会产生相同的错误 $em = $this->getDoc

我知道我这里有一个语法问题,但我想不出来。我试图对5个表进行选择和内部联接,但Symfony抱怨联接中的实体在定义之前就被使用了

实际错误如下:
[Semantical error]第0行,靠近'I ON C.id='的第121列:错误:标识变量MySiteBundle:在联接路径表达式中使用的项,但之前未定义。

下面是PHP代码

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

$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”:错误:类“Categories”没有定义。我的QB代码如下

$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();

有什么建议吗?

DQL不使用那样的联接。它们有点简化。然而,我也发现它们的文档记录不足

    $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();
实际使用的关系取决于您的模型

我通常使用查询生成器

    $em = $this->getEntityManager();
    $request = $em->getRepository('MySiteBundle:Categories');

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

路易斯在我打字时发了邮件。哦,好吧

DQL根据您的关联为您处理连接详细信息。通常,您只需要拼出FROM类名。比如:

'select C.name as CName, I.id as IId
FROM MySiteBundle:Categories C
INNER JOIN C.items');
并最终使用查询生成器

    $em = $this->getEntityManager();
    $request = $em->getRepository('MySiteBundle:Categories');

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

下面是一个在Symfony 2中使用查询生成器的示例

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();
}

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

在MemberItems控制器或MemberItems存储库中放置以下内容:

$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();

哼好的,我已经去掉了DQL代码,现在有了QB代码。我仍然得到
“类别”没有定义。
我已经在上面的原始问题中发布了完整的QB查询。我不想这么说,但你真的需要阅读关于查询的章节:然后从一个没有连接的简单查询开始,并添加到其中。添加symfony2命令,以便可以从命令行对其进行测试。如果你仍然有问题,那么发布你更新的查询。路易斯-谢谢你的回复,当我从DQL方式转到QB方式时,仍然会遇到一个非常类似的错误。我已经在我的原始问题中发布了这个错误和完整的查询。任何关于如何解决此问题的建议都将不胜感激!提前感谢。是的,您仍然坚持指定加入条件。你不需要那样做。条令会从你的模型中找到答案。检查我的查询是如何编写的。如果您仍然有问题,请提供有关模型的详细信息。您的意思是,条令将利用实体类中的关系来确定如何进行连接。问题是这个DB模式是由其他人创建的,并且不是所有的关系都存在。当我在数据库中添加这些关系,然后更新实体类时,我破坏了站点。我在多个页面上发现多个完整性约束冲突错误。此时,重写/修复这些页面不是一个选项,因此我现在无法利用实体类关系。这就是为什么我要显式地标识join中的表/列。建议??部分代码所有权不好。您不能在模型中添加关系吗?否则,您可能不得不回到SQL。我从来没有被困在这种情况下,我也帮不上什么忙。我只是想指出,这个原则实际上并不关心数据库约束是否存在。您可以将关系添加到实体类中,并保持数据库的原样。从一个简单的查询开始,按照手册进行操作。没有理由不这样做。