php - Eloquent 嵌套关系与一些约束

标签 php laravel laravel-4 eloquent

我有以下三个表:

A
-------------
| id | name |
-------------

B
--------------------
| id | A_id | name |
--------------------

C
--------------------
| id | B_id | name |
--------------------

因此,表C中的数据属于表B中的数据,表B中的数据属于表A中的数据。现在,我想查询 C,同时还从 BA 检索数据,下面的代码就可以很好地实现这一目的。

C::with('B.A')->get();

现在的问题是,我想在某些约束条件下查询 C。其中一个约束是 Aid。我尝试了以下方法:

C::with(array('B.A' => function ($query)
{
    $query->where('id', '=', $constraint);
}))->get();

但似乎 Eloquent 将检索 C 中的所有行,甚至不考虑约束,除非它正在执行查询以检索表 A 中的数据。我该如何解决这个问题?我是否需要在 C 中添加另一个字段,即 A_id,并将 $constraint 与该字段匹配?

最佳答案

您将 with() 方法与 SQL 的 JOIN 混淆了,这种情况经常发生。

先介绍一下背景

当你使用 Foo::with('bar')->where_something(1) 时,Laravel 将首先加载 Foo 然后根据 Foo.bar_id,它将加载 Bar。它的目的是告诉 Laravel 急切加载模型对组合查询的依赖性,从而大大提高这些模型的迭代性能。

如果你不使用它,应该执行以下查询:

SELECT * FROM foos WHERE foos.something = 1;
SELECT * FROM bars WHERE bars.id = 30;
SELECT * FROM bars WHERE bars.id = 57;
SELECT * FROM bars WHERE bars.id = 134;
SELECT * FROM bars WHERE bars.id = 1096;

如果你使用它,另一方面:

SELECT * FROM foos WHERE foos.something = 1;
SELECT * FROM bars WHERE bars.id IN (30, 57, 134, 1096); // Eager loading

当您向 with() 添加条件时,您只是限制了这些依赖项的预加载,而不是第一个查询。

现在回答你的问题

要实现您想要的效果,您需要使用 ->join()

C::with(array('b', 'b.a'))
 ->join('b', 'b.id', '=', 'c.b_id')
 ->join('a', 'a.id', '=', 'b.a_id')
 ->where('a.id', '=', $ID)
 ->get('c.*');

我包含了 with(),因为我不知道您是否需要访问 $c->b->a。如果您不这样做,并且您只需要 $c 数据,则可以删除 with(),因为它会不必要地查询 B 和 A。

关于php - Eloquent 嵌套关系与一些约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16789285/

相关文章:

php - CDbCriteria addConditions where 子句不明确

php - Laravel 5 中的 Multi-Tenancy 子域

php - Laravel 5 : How to create a custom attribute for a collection, 然后用它排序

php - Laravel 4 中带有自引用的 SQL 模式

Laravel 4:调用未定义的方法 Redis::connection()

php - 我无法使用此代码获取数据

php - PDO 期望数组在网页上不只返回 1 的 boolean 值

php - 比特币支付,OP_RETURN 参数

api - laravel 4 使用通配符的模式过滤器

many-to-many - 在多对多关系的情况下更新数据透视表 laravel4