简体   繁体   English

Doctrine 条件连接

[英]Doctrine Conditional joins

I'm trying to figure out how to achieve conditional joins in doctrine.我试图弄清楚如何在学说中实现条件连接。

I have an entity A with two fields, let's call them b (referencing a single B object) and c (referencing a single C object) respectively.我有一个带有两个字段的实体A ,让我们分别称它们为b (引用单个B对象)和c (引用单个C对象)。

/**
* @Entity
**/
class A
{
    /** @ManyToOne(targetEntity="B") **/
    protected $b;
    /** @OneToOne(targetEntity="C") **/
    protected $c;
}

I want to write a DQL query which is going to perform an INNER JOIN on $b ONLY if $b is not null, and if $b is null the INNER JOIN should be applied to $c instead (if $c is not null too).我想写这是要执行的一个DQL查询INNER JOIN$b仅当$b不为空,如果$b是空的INNER JOIN ,应适用于$c代替(如$c不为空太)。

I tried combining INNER JOINS with WITH clauses checking for null values, but this doesn't work obviously.我尝试将INNER JOINS与检查空值的WITH子句结合起来,但这显然不起作用。

SELECT a FROM model\entity\A a
INNER JOIN a.b ab WITH ab IS NOT NULL INNER JOIN ab.d abd (...)
INNER JOIN a.c ac WITH ac IS NOT NULL (...)

I also tried combining LEFT JOINS without success.我也尝试结合LEFT JOINS没有成功。

Long story short, here's the kind of DQL I'd like to obtain :长话短说,这是我想获得的 DQL 类型:

SELECT a FROM model\entity\A a
IF a.b IS NOT NULL INNER JOIN a.b ab WITH (...)
IF a.b IS NULL INNER JOIN a.c ac WITH (...)

I'll admit I don't even know if that kind of behaviour is achievable.我承认我什至不知道这种行为是否可以实现。 I think it would be easier to split this into two distinct queries, one joining on $b and the other joining on $c then merging the results myself, but I'd really like to find a single-query solution (provided there is any).我认为将其拆分为两个不同的查询会更容易,一个加入$b ,另一个加入$c然后自己合并结果,但我真的很想找到一个单查询解决方案(前提是有任何)。

Thanks for reading, and for any eventual help.感谢您的阅读,以及任何最终的帮助。

Cheers!干杯!

What you are describing is not possible in SQL, there is no concept of conditional joins because the structure of the result set must be consistent.你所描述的在 SQL 中是不可能的,没有条件连接的概念,因为结果集的结构必须是一致的。

DQL only enhances SQL in the respect of ORM mapping not in the respect of adding features not present in SQL. DQL 仅在 ORM 映射方面增强 SQL,而不是在添加 SQL 中不存在的功能方面。 On the contrairy DQL does not support SQL features not present in the SQL standards or which have no common ground between the major SQL RDBMS vendors -- ie: which are not supported by most vendors or have no equivalents in most vendors.相反,DQL 不支持 SQL 标准中不存在的 SQL 特性,或者在主要 SQL RDBMS 供应商之间没有共同点的 SQL 特性——即:大多数供应商不支持这些特性,或者在大多数供应商中没有等价物。

You can however build some PHP logic to help you with that;但是,您可以构建一些 PHP 逻辑来帮助您解决这个问题; for example you can use the Doctrine QueryBuilder to build the query based on PHP-level if conditions evaluated using pre-fetched PHP-level data.例如, if使用预取的 PHP 级别数据评估条件,则可以使用 Doctrine QueryBuilder 构建基于 PHP 级别的查询。

For example you could run a couple of DQL queries to pre-fetch the IDs from the ab IS NULL group and the ab IS NOT GROUP (separately) and then continue with one or more queries fetching the necessary data based on those IDs.例如,您可以运行几个 DQL 查询以从ab IS NULL组和ab IS NOT GROUP (单独)预取 ID,然后继续执行一个或多个查询,根据这些 ID 获取必要的数据。

Alternative solution found找到了替代解决方案

So I couldn't find a solution while working with conditions directly in the JOIN statements.所以我在JOIN语句中直接处理条件时找不到解决方案。 However, I decided to join all the entities I needed, and perform the condition checks in a classic WHERE statement.但是,我决定加入我需要的所有实体,并在经典的WHERE语句中执行条件检查。

If anyone runs into the same kind of issue, here's how I solved this :如果有人遇到同样的问题,这是我解决这个问题的方法:

Doesn't work :不起作用:

SELECT a FROM model\entity\A a
LEFT JOIN a.b ab WITH ab IS NOT NULL INNER JOIN ab.d abd (...)
LEFT JOIN a.c ac WITH ac IS NOT NULL (...)

Works :作品:

SELECT a FROM model\entity\A a
LEFT JOIN a.b ab
LEFT JOIN ab.d abd
LEFT JOIN a.c ac
WHERE ((ab IS NOT NULL AND (...)) OR (ac IS NOT NULL AND (...))) AND (...)

Thanks @Balmipour for telling me how to close this topic.感谢@Balmipour 告诉我如何结束这个话题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM