查询生成器/ DQL不能与INNER JOIN配合使用 - 语法问题

问题描述:

我知道我在这里有一个语法isse,但我无法弄清楚。我试图做5个表的SELECT和INNER JOIN,但Symfony抱怨JOIN中的实体在被定义之前使用。查询生成器/ DQL不能与INNER 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代码。

注意:我已将此查询缩短为两列,两个表格和一个连接,以便简化问题并显示我的观点。实际查询时间更长,并且产生相同的错误。

$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代码如下。

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

路易斯 - 感谢resonse,我还是从DQL方式向QB的方式移动时得到一个非常相似的错误。我已经在我的原始问题中发布了该错误和完整查询。有关如何解决这个问题的任何建议将不胜感激!提前致谢。 – ElasticThoughts 2012-02-22 21:24:27

+0

是的,你仍然坚持指定连接条件。你不需要那样做。学说将从你的模型中解释出来。检查我的查询是如何写入的。如果仍有问题,请提供有关模型的详细信息。 – 2012-02-22 21:27:15

+0

你认为Doctrine将利用Entity类中的关系来确定如何进行连接。问题在于这个数据库模式是由其他人创建的,并不是所有的关系都存在。当我将这些关系添加到数据库中,然后更新实体类时,我会中断该网站。我在多个页面上出现了多个完整性约束违规错误。重写/修复这些页面在这一点上不是一种选择,因此我目前无法利用实体类关系。这就是为什么我试图明确识别连接中的表格/列。建议? – ElasticThoughts 2012-02-23 12:02:37

Louis在我输入时发布。好吧。

DQL根据您的关联为您处理加入细节。一般来说,你只需要拼出FROM类的名字。例如:

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

并确定使用查询生成器。

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

这里是在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(); 
} 
+0

嗡嗡..好吧,我已经取消了DQL代码,现在有QB代码。我仍然没有定义''Categories''。我已经在上面的原始问题中发布了完整的QB查询。 – ElasticThoughts 2012-02-22 21:19:38

+0

我讨厌这样说,但你确实需要阅读关于查询的章节:http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/reference/query-builder.html然后从一个没有连接的简单查询并添加到它。添加一个symfony2命令,以便您可以从命令行对其进行测试。如果您仍有问题,请发布更新后的查询。 – Cerad 2012-02-23 19:34:30

您可能需要检查您的注释或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();