Doctrine2 / 查询鉴别器值
Doctrine2 / querying discriminator value
对于一个项目,我需要管理"cards"。
有 2 种卡片类型:"Client card" 和 "Member card"。
此应用程序的用户可以订购卡片。
为此,我使用 Type
鉴别器创建了一个抽象 Card
实体。
/* @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
知道我做错了什么吗?
与其说是你做错了什么,不如说是有一种方法可以解决这个问题。您可以通过以下方式 return 卡片类型。
在class卡中添加:
public function getCardType()
{
return $this->discr;
}
在class会员卡中添加:
protected $discr = 'member';
在class ClientCard 添加:
protected $discr = 'client';
对于一个项目,我需要管理"cards"。 有 2 种卡片类型:"Client card" 和 "Member card"。 此应用程序的用户可以订购卡片。
为此,我使用 Type
鉴别器创建了一个抽象 Card
实体。
/* @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
知道我做错了什么吗?
与其说是你做错了什么,不如说是有一种方法可以解决这个问题。您可以通过以下方式 return 卡片类型。
在class卡中添加:
public function getCardType()
{
return $this->discr;
}
在class会员卡中添加:
protected $discr = 'member';
在class ClientCard 添加:
protected $discr = 'client';