Symfony 2:使用理论查询构建器在非相关表上进行 INNER JOIN

Posted

技术标签:

【中文标题】Symfony 2:使用理论查询构建器在非相关表上进行 INNER JOIN【英文标题】:Symfony 2: INNER JOIN on non related table with doctrine query builder 【发布时间】:2012-06-22 09:43:11 【问题描述】:

我正在尝试使用原则查询构建器构建一个查询,该查询构建器连接一个不相关的表,如下所示:

$query = $this->createQueryBuilder('gpr')
        ->select('gpr, p')
        ->innerJoin('TPost', 'p')
        ->where('gpr.contentId = p.contentId')

但这不起作用。我仍然收到错误:

错误:连接路径表达式中使用了标识变量 TPost,但之前未定义。

我搜索了此错误消息,每个人都回答使用表别名 + 属性,如 p.someAttribute。但我要加入的表与我开始选择的表无关。

作为一个普通的mysql查询,我会这样写:

SELECT * FROM t_group_publication_rel gpr 
INNER JOIN t_post p 
WHERE gpr.content_id = p.content_id

任何想法我做错了什么?

【问题讨论】:

我们可以使用 DQL 与不相关的对象执行连接吗?我不知道。如果可能的话,这很有趣 =)。 如果你想加入他们,为什么不直接建立这两者之间的关系? 在这种情况下,一个关系是不够的。我需要与 3 个不同表的关系,并且任何记录只能设置对这 3 个表中的 1 个的引用。 如果我在控制器中使用 find 方法而不是构建查询会更慢吗?我会说是的,因为后台有更多的查询,对吧? 所以我的意思不仅仅是一种查找方法。循环中 2 个不同的发现的组合。 【参考方案1】:

只有在映射中定义了关联时,DQL 连接才有效。在您的情况下,我会说执行本机查询并使用 ResultSetMapping 填充您的对象要容易得多。

【讨论】:

【参考方案2】:

今天我正在处理类似的任务,并记得我打开了这个问题。我不知道它是从哪个教义版本开始工作的,但现在您可以轻松地将子类加入继承映射中。所以像这样的查询没有任何问题:

$query = $this->createQueryBuilder('c')
        ->select('c')
        ->leftJoin('MyBundleName:ChildOne', 'co', 'WITH', 'co.id = c.id')
        ->leftJoin('MyBundleName:ChildTwo', 'ct', 'WITH', 'ct.id = c.id')
        ->orderBy('c.createdAt', 'DESC')
        ->where('co.group = :group OR ct.group = :group')
        ->setParameter('group', $group)
        ->setMaxResults(20);

我在使用继承映射的父类中启动查询。在我之前的帖子中,如果我没记错的话,这是一个不同的起点,但同样的问题。

因为当我开始这个问题时它是一个大问题,所以我认为对于其他不了解它的人来说也可能很有趣。

【讨论】:

谢谢!这真的很有帮助,我一直在寻找几个小时。 如果我没有MyBundleName:ChildTwo 存储库,我想用表名编写查询,那么解决方案是什么。? @MohammadFareed 对实体的引用不是存储库,它是 ':' 形式的字符串或实体类的 FQCN,例如\AppBundle\Entity\ChildTwo::class 使用 WITH 或 ON 有什么区别?【参考方案3】:
$dql = "SELECT 
    a, md.fisrtName , md.LastName, mj
    FROM MembersBundle:Memberdata md
        INNER JOIN MembersBundle:Address a WITH md = a.empID
        INNER JOIN MembersBundle:Memberjob mj WITH md = mj.memberData
            ...
    WHERE
        a.dateOfChange IS NULL
    AND WHERE
        md.someField = 'SomeValue'";

return $em->createQuery( $dql )->getResult();

【讨论】:

虽然这个答案没有提供所需的详细信息,但没有什么可引用的,因为 Doctrine 的文档完全没有涵盖这些类型的连接。这对我有用。我知道足够多的 sql 来解析预期的内容,而没有足够的学说来连接这些点。【参考方案4】:

在 2.4 版之前,没有关联的实体之间的连接是不可能的,您可以使用以下语法生成任意连接:

$query = $em->createQuery('SELECT u FROM User u JOIN Blacklist b WITH u.email = b.email');

参考:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html

【讨论】:

这太棒了!请注意,在这种情况下需要WITH 子句,否则会导致语法错误。但是,您可以只使用一个虚拟条件并从本质上获得一个真正的交叉连接,否则 DQL 不支持。例如:SELECT u FROM User u JOIN Items i WITH 0 = 0。这对于复杂的统计数据很有用。

以上是关于Symfony 2:使用理论查询构建器在非相关表上进行 INNER JOIN的主要内容,如果未能解决你的问题,请参考以下文章

使用查询构建器在 Laravel 中添加全文索引

通过 CLI 包装器在非托管 C++ 中使用 C#.NET Winform - 需要线程?

Laravel - 使用 Eloquent 查询构建器在选择中添加自定义列

如何使用 symfony 在教义查询构建器中选择表之间的特定连接?

FatalErrorException:错误:在非对象 symfony 上调用成员函数 has()

使用查询构建器和 Symfony 的预订系统