laravel eloquent - 在嵌套急切加载的关系上不使用

Posted

技术标签:

【中文标题】laravel eloquent - 在嵌套急切加载的关系上不使用【英文标题】:laravel eloquent - Use without on nested eager loaded relations 【发布时间】:2020-05-28 10:30:45 【问题描述】:

我目前正在开发 laravel 框架,但遇到了一些关系和急切的加载问题。

情况

我有三个模型 A、B 和 C

我有两个关系

A 有很多 B B 有很多 C

默认情况下(使用模型中的 $with 属性):

A 不包括 B B 包括 C

所以大部分时间我都在使用没有 B 的 A 和使用 C 的 B

这是我设置关系方法和预加载的方式

class A extends Model 
...

  protected $with = [];

  public function bs() 
      return $this->hasMany('App\Models\B');
  



class B extends Model 
...

  protected $with = ['cs'];

  public function cs() 
      return $this->hasMany('App\Models\C');
  

  public function a() 
      return $this->belongsTo('App\Models\A');
  


class C extends Model 
...

  public function b() 
      return $this->belongsTo('App\Models\B');
  

问题

对于一个特定的任务,我想用所有 B 和没有任何 C 来查询 A

当我使用A::query()->with('b')时默认加载C

所以我正在尝试使用A::query()->with('b')->without('b.c') 但它一直在加载 B 到 C 的关系。

您对如何实现这一点有任何想法吗?

感谢您的帮助!

【问题讨论】:

你能准确地展示你的模型内部是什么样子 - 特别是你是如何设置关系方法的吗? 我更新了我的帖子 如果您使用受保护的 $with = ['cs'] 并且不想加载 b,则只需添加没有,如下所示 public function cs() return $this->hasMany('应用\模型\C')->没有('b'); 【参考方案1】:

Eloquent\Model 有一个newQueryWithoutRelationships

我认为您可以执行以下操作:

(new A())->newQueryWithoutRelationships()->with(...)

comment之后更新

有趣的方法without()(不知道)。

看来您可以尝试以下方法:

A::query()->with(['bs' => function($query) 
    $query->without('c');
]);

【讨论】:

不,它不起作用...newQueryWithoutRelationships() 删除模型 A 的关系,但不删除我使用 with()statement 添加的关系.. 答案的更新部分对我不起作用。使用 $query->without('c'); 仍然返回 c【参考方案2】:

发生这种情况是因为您使用了 B 类:

protected $with = ['cs'];

这将急切地加载 cs() 与每个查询的关系。

删除后,您应该会看到

A::query()->with('b')

将仅加载关联的 B 模型,而不加载其对应的 C

【讨论】:

是的,我知道!我的问题是,有没有办法保持我急切的负载(因为这是我的应用程序的常见情况)但仅针对一个请求将其删除?

以上是关于laravel eloquent - 在嵌套急切加载的关系上不使用的主要内容,如果未能解决你的问题,请参考以下文章

laravel 嵌套急切加载获取和第一个函数

Laravel 在急切加载时使用 Eloquent 选择特定列

急切加载 Laravel Eloquent 相关模型

Laravel Eloquent 中的急切加载

带有约束的 Laravel 嵌套急切加载

带有嵌套关系的 Laravel 急切加载