【问题标题】:Yii2 Adding SearchModel Many-to-Many relationships produces duplicative resultsYii2 添加 SearchModel 多对多关系会产生重复的结果
【发布时间】:2017-04-12 21:40:45
【问题描述】:

我有一个具有六个多对多关系的模型。当我在 SearchModel 中添加 joinWith 条目,然后查看 index.php 视图中返回的内容(未应用搜索参数)时,它显示的行数比基本模型中的实际行数多得多。经过进一步检查,我发现正在返回多个重复的行。它也抛出了分页方式。例如,如果我在 SearchModel 中只添加一个 joinWith 并且我将分页设置为每页 10 行,这就是发生的情况。在有 175 行的基本模型中,第一页将显示“1-4 of 425 items”。第二页将显示“111-16 of 425 items”。第一页的最后一项复制到第二页的顶部。提供一些背景:

基础模型有以下关系:

/**
     * @return \yii\db\ActiveQuery
     */
    public function getHerbalHerbsHerbalPreparations()
    {
        return $this->hasMany(\common\models\HerbalHerbsHerbalPreparations::className(),
                              ['herbal_preparation_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getHerbalHerbs()
    {
        return $this->hasMany(\common\models\HerbalHerbs::className(), ['id' => 'herbal_herb_id'])
                    ->viaTable('herbal_herbs_herbal_preparations', ['herbal_preparation_id' => 'id']);
    } */

在 SearchModel 中,我有这个条目:

$query = HerbalPreparations::find()->joinWith('herbalHerbs');

请注意,如果我为急切加载和连接类型添加可选的 joinWith 参数,这没有任何区别。 `$query = HerbalPreparations::find()->joinWith('herbalHerbs', true, 'LEFT JOIN');产生相同的结果。

没有任何 joinWith,index.php 视图如下所示:

通过上面描述的joinWith,index.php的第1页看起来像这样:

index.php 视图的第 2 页看起来像:

注意第 1 页的最后一行和第 2 页的第一行的重复。

不用说,如果我用 joinWith 指定额外的多对多关系,这个问题会呈指数级恶化。

如果我真的使用 GridView 过滤器或搜索表单输入搜索参数,它会完美运行。问题是 index.php 视图需要在没有搜索参数的情况下正常工作。

对于在任何类型的高级应用程序中使用 Yii2 的任何人来说,这似乎都是一个常见问题。我确定我一定做错了什么,但我搜索了谷歌,直到我筋疲力尽并且找不到任何帮助。 `

【问题讨论】:

  • 只有当搜索输入字段不为空时,一个快速的解决方案可能是实现->joinWith('herbalHerbs');
  • 这听起来会让 joinWith 变得非常复杂,只是为了做一些地球上每个 Web 开发人员都需要的标准、日常、规范的过程。当然,Yii2 已经为这样一个完全常见的问题实施了解决方案。当您添加它时,这将是最终产品中的->joinWith('herbalHerbs', 'herbalAilments', 'herbalMedicinalUses', 'herbalProperties', 'herbalTags'),检查每一个确实非常复杂。

标签: search join yii2 relationship


【解决方案1】:

我不能对这个答案负责。实际上,Yii 论坛的新手给出了这样的答案。它实际上相当简单——只需添加一个groupBy('id')。比如

$query = HerbalPreparations::find()->joinWith('herbalHerbs', true, 'LEFT JOIN')->groupBy(['id']);

我想我应该能够从 SQL 的基本知识中弄清楚这一点,但我从来没有以这种方式使用 groupBy。

这似乎是一种常见的需求,我认为它会被记录下来,并且几乎可以在任何地方通过简单的搜索找到。不幸的是,它似乎不是。

【讨论】:

    猜你喜欢
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 1970-01-01
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多