带有连接表的 Doctrine 查询生成器 ManyToMany

问题描述 投票:0回答:2

我尝试通过学说查询构建器构建类似这样的查询:

SELECT m.id
FROM product p, model m
  INNER JOIN product_model pm ON (m.id = pm.model_id)
WHERE p.id = pm.product_id AND m.serial = ? AND p.id = ?

Table

product_model
是`ManyToMany 单向关系中的JoinTable。我使用下面的代码:

$queryBuilder = $this->entityManager->createQueryBuilder();
        $queryBuilder
            ->select('m.id')
            ->from(Model::class, 'm')
            ->join(Product::class, 'p', Join::ON, '1 = 1')
            ->where('m.serial.serial = :serial')
            ->andWhere('p.productId.id = :productId')
            ->setParameters([
                'serial'    => (string)$serial,
                'productId' => $productId->value(),
            ]);
        $query = $queryBuilder->getQuery();
        $results = $query->getOneOrNullResult();

但是当我尝试转储此查询的 SQL 时,我得到:

SELECT m0_.id AS id_0 
FROM model m0_ 
  INNER JOIN product p1_ ON (1 = 1) 
WHERE m0_.serial = ? AND p1_.id = ?

这个查询的结果不是我所期望的

php doctrine-orm
2个回答
0
投票

我找到了解决方案。我需要另一个带有复合键的 Product_model 表实体类,并且查询中的变化很小:

$queryBuilder
            ->select('m.id')
            ->from(Model::class, 'm')
            ->join(ProductModel::class, 'pm', Join::WITH, $queryBuilder->expr()->eq('m.id', 'pm.modelId'))
            ->where('m.serial.serial = :serial')
            ->andWhere('pm.productId = :productId')
            ->setParameters(
                [
                    'serial'    => (string)$serial,
                    'productId' => $productId->value(),
                ]
            );

0
投票

答案应该更简单。

如果连接表仅包含 id 而没有其他数据,则不应将其声明为实体。在使用 Doctrine 时,我从未在任何项目中使用过连接表。

参见。 :https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html

我认为这应该有效:

$queryBuilder
        ->select('m.id')
        ->from(Model::class, 'm')
        ->join(Product::class, 'p')
        ->where('m.serial.serial = :serial')
        ->setParameters(
            [
                'serial'    => (string)$serial,
            ]
        );
© www.soinside.com 2019 - 2024. All rights reserved.