【问题标题】:Doctrine QueryBuilder need change ON condition for leftJoinDoctrine QueryBuilder 需要更改 leftJoin 的 ON 条件
【发布时间】:2017-12-29 11:01:10
【问题描述】:

当有条件或条件时,我有带有左连接的本机 sql 查询,如何在查询生成器中表示它?

 $query = "  SELECT  te.id
            FROM    task_executions AS te
            INNER JOIN tasks AS t ON t.id = te.task_id
            LEFT JOIN cost_objects AS co ON co.id = t.cost_object_id
            LEFT JOIN cost_object_managers AS com ON com.cost_object_id = co.id OR com.cost_object_id = co.parent_id

我需要在查询生成器中表示它。但是在User 实体中,我有ManyToMany 关系,没有单独的表,当我尝试左连接WITH 条件时,这与我需要的不同。我需要更改ON的关系

LEFT JOIN cost_object_managers AS com ON com.cost_object_id = co.id OR com.cost_object_id = co.parent_id

用户实体

class User
{
...
/**
 * @ORM\ManyToMany(targetEntity="CostObject", mappedBy="users")
 */
private $costObjects;
}

成本对象实体

class CostObject
{
    /**
 * @var CostObject
 *
 * @ORM\ManyToOne(targetEntity="CostObject", inversedBy="children")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
 * })
 */
private $parent;

    /**
 * @var ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="User", inversedBy="costObjects")
 * @ORM\JoinTable(name="cost_object_managers",
 *      joinColumns={@ORM\JoinColumn(name="cost_object_id", referencedColumnName="id", onDelete="CASCADE")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")}
 * )
 */
private $users;

和我的无条件查询生成器

        $qb->select('te')
        ->from('AppBundle:TaskExecution', 'te')
        ->innerJoin('te.task', 't')

        ->leftJoin('t.costObject', 'co')
        ->leftJoin('co.users', 'com')

这是$query->getSQL()

SELECT some_name FROM task_executions t0_ INNER JOIN tasks t1_ ON t0_.task_id = t1_.id LEFT JOIN cost_objects c2_ ON t1_.cost_object_id = c2_.id LEFT JOIN cost_object_managers c4_ ON c2_.id = c4_.cost_object_id LEFT JOIN users u3_ ON u3_.id = c4_.user_id ORDER BY t0_.execution_start DESC

在这个例子中,我看到ON 关系条件LEFT JOIN users u3_ ON u3_.id = c4_.user_id。并且需要像在本机 sql 中一样更改它

现在我有

        $qb->select('te')
        ->from('AppBundle:TaskExecution', 'te')
        ->innerJoin('te.task', 't')
        ->leftJoin('t.costObject', 'co')
        ->leftJoin(
            'co.users',
            'com',
            Join::ON,
            $qb->expr()->orX(
                'co = com.costObjects',
                'co.parent = com.costObjects'
            )
        )

但出现错误

[Syntax Error] line 0, col 112: Error: Expected end of string, got 'ON'

如果我使用WITH 条件,在我的sql 中表示我仍然有id 关系,我不需要那个

            ->leftJoin(
            'co.users',
            'com',
            Join::WITH,
            $qb->expr()->orX(
                'co MEMBER OF com.costObjects',
                'co.parent MEMBER OF com.costObjects'
            )
        )

LEFT JOIN users u3_ ON u3_.id = c4_.user_id AND (EXISTS (SELECT 1 FROM cost_object_managers c5_ INNER JOIN cost_objects c6_ ON c5_.cost_object_id = c6_.id WHERE c5_.user_id = u3_.id AND c6_.id IN (c2_.id)) OR EXISTS (SELECT 1 FROM cost_object_managers c5_ INNER JOIN cost_objects c6_ ON c5_.cost_object_id = c6_.id WHERE c5_.user_id = u3_.id AND c6_.id IN (c2_.parent_id)))

我的意思是 users u3_ ON u3_.id = c4_.user_id AND 但在本机查询中我们只有 LEFT JOIN cost_object_managers AS com ON com.cost_object_id = co.id OR com.cost_object_id = co.parent_id

它如何在具有ON 条件类型的查询生成器中重现?

【问题讨论】:

  • 我用过 Symfony。我需要查询生成器代表

标签: php mysql sql-server symfony doctrine-orm


【解决方案1】:

如果您有查询并且它适用于您,则无需执行所有工作来将其转换为 DQL 或 QueryBuilder 编程语法。您可以只使用 Doctrine 的本机查询,然后 - 如果需要 - 将结果映射到您的对象。只需创建一个自定义存储库,并在其中添加一个大致如下所示的新方法:

public function findTaskExecutionBy...()
{
    $query = $this->entityManager->createNativeQuery('SELECT te.id FROM ...');

    return $query->getSingleScalarResult(); // If it's just one id you expect
}

如果您希望返回多个 id,也可以使用 $query->getResult()。或者,如果您想要整个任务对象,请使用 ResultSetMapping:

$rsm = new ResultSetMappingBuilder($this->entityManager);
$rsm->addRootEntityFromClassMetadata('App\Entity\Task', 'te');

$query = $this->entityManager->createNativeQuery(
    'SELECT te.* FROM ...',

您还可以查看 Doctrine 文档以获取更详细的解释和更多示例:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/native-sql.html $rsm );

【讨论】:

  • 非常好的建议如果您有查询并且它适合您,您不需要做所有工作来将其转换为 DQL
  • 就我而言,我需要查询生成器查询
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 1970-01-01
  • 2020-01-10
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多