【问题标题】:How can I filter doctrine query by related id (Symfony 4)?如何按相关 id (Symfony 4) 过滤学说查询?
【发布时间】:2019-02-12 13:02:52
【问题描述】:

在我的实体中:

  /**
  * @ORM\ManyToMany(targetEntity="Productgroup", inversedBy="fields")
  * @ORM\JoinColumn(name="productgroup", referencedColumnName="id")
  */
  private $productgroup;

  public function getProductgroup()
  {
    return $this->productgroup;
  }

  public function setProductgroup($productgroup): self
  {
    $this->productgroup = $productgroup;

    return $this;
  }

  public function __construct()
  {
    $this->productgroup = new ArrayCollection();
  }

在我的控制器中:

$group = $this->getDoctrine()->getRepository(class::fields)->findAll();

输出:

array:2 [▼
  0 => Fields {#120842 ▼
    -id: 3
    -name: "cat"
    -unique_id: "5a38c820ed"
    -productgroup: PersistentCollection {#120846 ▼
      -snapshot: array:1 [ …1]
      -owner: Fields {#120842}
      -association: array:20 [ …20]
      -em: EntityManager {#114768 …11}
      -backRefFieldName: "fields"
      -typeClass: ClassMetadata {#119877 …}
      -isDirty: false
      #collection: ArrayCollection {#120847 ▼
        -elements: array:1 [▼
          0 => Productgroup {#120528 ▼
            -id: 6
            -name: "Animals"
            -unique_id: "9e4ef1c46f"
            -fields: PersistentCollection {#120739 ▶}
          }
        ]
      }
      #initialized: true
    }
    -type: Type {#120923 ▶}
  }
  1 => Fields {#120924 ▼
    -id: 5
    -name: "horse"
    -unique_id: "c3890b9287"
    -productgroup: PersistentCollection {#120925 ▼
      -snapshot: []
      -owner: Fields {#120924}
      -association: array:20 [ …20]
      -em: EntityManager {#114768 …11}
      -backRefFieldName: "fields"
      -typeClass: ClassMetadata {#119877 …}
      -isDirty: false
      #collection: ArrayCollection {#120926 ▼
        -elements: []
      }
      #initialized: false
    }
    -type: Type {#120927 ▶}
  }
]

我现在想过滤所有$group 以仅输出未连接到ID 为6 的产品组的字段。我的做法:

在我的控制器中:

$group = $this->getDoctrine()->getRepository(class:fields)->filterByColletion(6);

在我的存储库中:

 public function filterByColletion($id)
    {
      return $this->createQueryBuilder('p')
      ->addSelect('f')
      ->from('App\Entity\Fields', 'f')
      ->leftJoin('f.productgroup', 'productgroup')
      ->andWhere('f.productgroup != 6')
      ->getQuery()
      ->execute();
    }

错误是

无效的路径表达式。 StateFieldPathExpression 或 应为 SingleValuedAssociationField

因此,我希望只有组包含 horse

【问题讨论】:

    标签: symfony filter doctrine arraycollection


    【解决方案1】:

    您的查询中有->andWhere('f.productgroup != 6'),但f.productgroup 不是纯值字段,而是关系。您需要将您的条件应用于值字段,所以它会是这样的:

    ->leftJoin('f.productgroup', 'pg')
    ->andWhere('pg.id != 6')
    

    我在本例中使用了pg.id,但您需要使用您要对其应用条件的Productgroup 实体中的实际值字段名称。

    旁注:最好不要将值直接嵌入到查询中,而是将其作为参数传递:

    ->leftJoin('f.productgroup', 'pg')
    ->andWhere('pg.id != :id')
    ->setParameter(':id', 6)
    

    【讨论】:

    • 谢谢,我测试了你的代码,但现在输出只有[] 完全是空数组。没有错误信息。但我希望,数组中有马
    • 由于您正在使用 Symfony - 我建议您启用开发人员工具栏(如果还没有)并查看您请求的“Doctrine”选项卡。它包含请求期间进行的所有查询的日志以及 Doctrine 生成的实际 SQL 查询。查看实际查询,也许它会给您提示您的案例出了什么问题
    • 我查过了。在列表中找不到此请求。我发现直到现在我必须删除->addSelect('f')。如果我写->andWhere('pg.id = :id'),那么它会显示我上面的示例中的数组
    • 我认为andWhere 在这种情况下是错误的。因为我需要弄清楚关系
    • 如果您在存储库中使用 createQueryBuilder() - 您可以省略 select()from() 子句,因为在这种情况下它们是 applied automatically
    【解决方案2】:

    您可以使用 IDENTITY() DQL 函数跳过左连接:

                ->andWhere('IDENTITY(f.productgroup) != :productgroup_id')
                ->setParameter('productgroup_id', $id);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-22
      • 1970-01-01
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      • 2014-09-27
      相关资源
      最近更新 更多