gpt4 book ai didi

CakePHP 多重嵌套连接

转载 作者:行者123 更新时间:2023-12-02 02:34:14 25 4
gpt4 key购买 nike

我有一个应用程序,其中几个模型由 hasMany/belongsTo 关联链接。例如,A 有许多 B,B 有许多 C,C 有许多 D,D 有许多 E。此外,E 属于 D,D 属于 C,C 属于 B,B 属于 A。使用 Containable 行为非常适合控制每个查询返回的信息量,但是在使用涉及表 D 的条件时尝试从表 A 获取数据时我似乎遇到了问题。例如,这是我的“A”的示例型号:

class A extends AppModel {
var $name = 'A';

var $hasMany = array(
'B' => array('dependent' => true)
);

function findDependentOnE($condition) {
return $this->find('all', array(
'contain' => array(
'B' => array(
'C' => array(
'D' => array(
'E' => array(
'conditions' => array(
'E.myfield' => $some_value
)
)
)
)
)
)
));
}
}

这仍然给我返回“A”中的所有记录,如果相关的“E”记录不满足条件,那么我就得到这个:

Array(
[0] => array(
[A] => array(
[field1] => // stuff
[field2] => // more stuff
// ...etc
),
[B] => array(
[field1] => // stuff
[field2] => // more stuff
// ...etc
),
[C] => array(
[field1] => // stuff
[field2] => // more stuff
// ...etc
),
[D] => array(
[field1] => // stuff
[field2] => // more stuff
// ...etc
),
[E] => array(
// empty if 'E.myfield' != $some_value'
)
),
[1] => array( // ...etc )
)

当 If 'E.myfield' != $some_value 时,我根本不想返回记录。

我希望这足以清楚地表达我的问题...

基本上,我想要以下查询,但采用与数据库无关/CakePHP-y 的方式:

SELECT * 
FROM A INNER JOIN
(B INNER JOIN
(C INNER JOIN
(D INNER JOIN
E ON D.id=E.d_id)
ON C.id=D.c_id)
ON B.id=C.b_id)
ON A.id=B.a_id
WHERE E.myfield = $some_value

最佳答案

您的问题是对 Containable 行为的作用以及 Model::findcontain 选项的作用的误解。您的第一个代码示例中的 Model::find 调用将大致转换为:

Find all A; then find all B associated with each A; then find all C associated with each B; then find all D associated with each C; finally, find all E associated with each D where one field in E matches a specified value.

条件语句只过滤 D 的结果,而不是向上过滤到 C,然后是 B,然后是 A。如果你扫描 SQL 日志,你会看到大量的查询拉出你的 的每一层包含 链。

为了让 CakePHP 直接从数据库返回您想要的结果,您必须在 A 和 E 之间配置一个 hasOne 关联。使用您描述的长链,这可能相当笨拙。它看起来像(阅读:未经测试):

$this->bindModel(array('hasOne'=>array(
'B'=>array(
'foreignKey' => false,
'conditions' => array('A.id = B.a_id')
),
'C'=>array(
'foreignKey' => false,
'conditions' => array('B.id = C.b_id')
),
'D'=>array(
'foreignKey' => false,
'conditions' => array('C.id = D.c_id')
),
'E'=>array(
'foreignKey' => false,
'conditions' => array('D.id = E.d_id')
)
)));

$this->find('all', array(
'conditions' => array( 'E.my_field' => $some_value )
));

另一种方法是从 Model::find 调用中完全删除 E.my_value 条件,而是执行相当复杂的 Set::extract 最后:

$results = $this->find('all', array(
'contain' => array(
'B' => array(
'C' => array(
'D' => array(
'E' => array()
)
)
)
)
));
return Set::extract("/A/B/C/D/E[my_field={$some_value}]/../../../../", $results);

但是,对于深度 Set::extract,性能将是一个真正的问题,尤其是当您在很多行上进行操作时。

编辑:我只想强调,如果此操作需要扩展,Set::extract 选项是多么糟糕的想法。它将数据库引擎的整个过滤负担转移到 PHP 的数组函数上。

关于CakePHP 多重嵌套连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2516201/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com