Doctrine2 WHERE on optional JOIN

Doctrine2 WHERE on optional JOIN

这失败了

$builder = $repo->createQueryBuilder("ub")
    ->where("ub.badge = :badge AND ub.user = :user AND ub.project = :project")
    ->setMaxResults(1)
    ->setParameter("project", $project)
    ->setParameter("user", $user)
    ->setParameter("badge", $badge);

project 可能存在也可能不存在并导致此错误

Binding entities to query parameters only allowed for entities that have an identifier

如果将查询更改为以下,它仍然失败,提示它是项目而不是任何其他实体。即使 ub (UserBadge) table.

中没有行,这仍然会失败
$builder = $userBadgesRepo->createQueryBuilder("ub")
    ->where("ub.project = :project")
    ->setMaxResults(1)
    ->setParameter("project", $project);

如何更改此查询以在 WHERE 语句中使用 project

UserBadge YML

Acme\NameBundle\Entity\UserBadges:
    type: entity
    table: user_badges
    repositoryClass: Acme\NameBundle\Entity\UserBadgesRepository
    fields:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO

        added:
            type: datetime

    manyToOne:
        badge:
            targetEntity: Acme\NameBundle\Entity\Badge
            inversedBy: badge_users
            joinColumn:
                onDelete: CASCADE
                name: badge_id
                referencedColumnName: id
        user:
            targetEntity: Acme\NameBundle\Entity\User
            inversedBy: user_badges
            joinColumn:
                onDelete: CASCADE
                name: user_id
                referencedColumnName: id
        project:
            targetEntity: Acme\NameBundle\Entity\Project
            inversedBy: project_badges
            joinColumn:
                onDelete: CASCADE
                name: project_id
                referencedColumnName: id
                nullable: true

YML 项目

Acme\NameBundle\Entity\Project:
    type: entity
    table: project
    repositoryClass: Acme\NameBundle\Entity\ProjectRepository
    fields:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
**SNIP**

    oneToMany:
         project_badges:
             targetEntity: Acme\NameBundle\Entity\UserBadges
             mappedBy: project

这应该有效:

$builder = $repo->createQueryBuilder("ub")
    ->leftJoin('ub.project', 'p')
    ->join('ub.badge', 'b')
    ->join('ub.user', 'u')
    ->where("b.id = :badge AND u.id = :user AND p.id = :project")
    ->setMaxResults(1)
    ->setParameter("project", $project->getId())
    ->setParameter("user", $user->getId())
    ->setParameter("badge", $badge->getId());

解释(摘自评论):

关系是通过引用 (id) 存储的,您可以通过这些直接查询,但不能通过对象本身进行查询,因为在查询时 sql 不知道 table另一个实体的。您只能在手动加入关系对象后进行比较。

请同时阅读此处的第 5 部分:http://labs.octivi.com/mastering-symfony2-performance-doctrine