Doctrine2 /查询鉴别器值

时间:2016-04-18 11:13:00

标签: php symfony doctrine-orm zend-framework2

对于一个项目,我需要管理“卡片”。 有两种卡类型:“客户卡”和“会员卡”。 卡可以由此应用程序的用户订购。

为实现这一目标,我使用Card鉴别器创建了一个抽象的Type实体。

/* @ORM\Entity
 * @ORM\Table(name="cards")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({"member"="MemberCard", "client"="ClientCard"})
 */
abstract class Card
{
    const MEMBER = 'member';
    const CLIENT = 'client';

    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="CardsOrder", inversedBy="cards")
     * @ORM\JoinColumn(name="order_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $order;

    /**
     * Return the card type
     *
     * @return string
     */
    abstract public function getType();

    /**
     * @return mixed
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @param CardsOrder $order
     *
     * @return $this
     */
    public function setOrder(CardsOrder $order)
    {
        $this->order = $order;

        return $this;
    }

    /**
     * @return CardsOrder
     */
    public function getOrder()
    {
        return $this->order;
    }
}

MemberCard实体

/**
 * @ORM\Entity
 */
class MemberCard extends Card
{

    /**
     * @ORM\ManyToOne(targetEntity="Member", inversedBy="cards")
     * @ORM\JoinColumn(name="member_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $member;

    /**
     * @param Member $member
     *
     * @return $this
     */
    public function setMember(Member $member)
    {
        $this->member = $member;

        return $this;
    }

    /**
     * @return Member
     */
    public function getMember()
    {
        return $this->member;
    }

    /**
     * @return string
     */
    public function getType()
    {
        return self::MEMBER;
    }
}

ClientCard实体

/**
 * @ORM\Entity
 */
class ClientCard extends Card
{

    /**
     * ClientCard - client n-1 relation
     *
     * @ORM\ManyToOne(targetEntity="Client", inversedBy="cards")
     * @ORM\JoinColumn(name="client_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $client;

    /**
     * @param \Admin\Crm\Entity\Client\Client $client
     *
     * @return $this
     */
    public function setClient(Client $client)
    {
        $this->client = $client;

        return $this;
    }

    /**
     * @return Client
     */
    public function getClient()
    {
        return $this->client;
    }

    /**
     * @return string
     */
    public function getType()
    {
        return self::CLIENT;
    }

}

现在,我想知道某个成员或客户是否有待定的订购卡(状态是二进制状态标志):

public function findPendingCard($clientOrMember)
{
    // $this->getRepository is the Card repository, injected in a factory
    $query = $this->getRepository()->createQueryBuilder('c')
                      ->join('c.order', 'o', 'WITH', 'BIT_AND(o.status, :oStatus) > 0')
                      ->where('c INSTANCE OF :memberCardEntity AND c.member = :clientOrMember')
                      ->orWhere('c INSTANCE OF :clientCardEntity AND c.client = :clientOrMember')
                      ->setParameters([
                          'oStatus'        => CardsOrder::OPEN,
                          'clientOrMember' => $clientOrMember,
                          'memberCardEntity'   => MemberCard::class,
                          'clientCardEntity'   => ClientCard::class,
                      ])
                      ->getQuery();

        return $query->getOneOrNullResult();
    }

但我收到了这个错误:

[Semantical Error] line 0, col 148 near 'member = :clientOrMember)': Error: Class Card has no field or association named member

知道我做错了吗?

1 个答案:

答案 0 :(得分:1)

并不是说你做错了什么,但有一种方法可以解决这个问题。您可以使用以下内容返回卡片类型。

在课程卡片中添加:

protected $discr = 'member';
在MemberCard类中添加:

protected $discr = 'client';
在ClientCard类中添加:

<?php

 namespace Colleen\Core\Event\Application;

final class ApplicationBootedEvents
{
  const APP_BOOTED = 'application.booted';
 }