我有以下三个表:
A
-------------
| id | name |
-------------
B
--------------------
| id | A_id | name |
--------------------
C
--------------------
| id | B_id | name |
--------------------
因此,表C
中的数据属于表B
中的数据,该数据属于表A
中的数据。现在,我想查询C
,同时还从B
和A
检索数据,以下代码就可以了。xt / p>
C::with('B.A')->get();
现在的问题是,我想用一些约束来查询C
。其中一个约束是id
的{{1}}。我尝试了以下内容:
A
但似乎Eloquent将检索C::with(array('B.A' => function ($query)
{
$query->where('id', '=', $constraint);
}))->get();
中的所有行,甚至不考虑约束,除非它正在执行查询以检索表C
中的数据。我该如何解决这个问题?我是否需要在A
中添加另一个字段C
,并在该字段中匹配A_id
?
答案 0 :(得分:20)
您将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。