如何用Backing Table建模软枚举?Doctrine关联过滤问题求解
Doctrine ORM 关联外部表时限定过滤条件的配置方案
针对你遇到的外部表partner和code关联时,因code值重复导致获取错误label的问题,正确的做法是在Partner实体的关联定义中,通过复合关联条件限定code表的set字段值,确保status关联set=1的记录、salutation关联set=2的记录。
步骤1:映射Code实体(外部只读表)
首先正确映射code表的实体,标记为只读避免Doctrine修改数据:
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(readOnly=true) * @ORM\Table(name="code") */ class Code { /** * @ORM\Id * @ORM\Column(name="code", type="string") */ private string $code; /** * @ORM\Column(name="set", type="integer") */ private int $set; /** * @ORM\Column(name="label", type="string") */ private string $label; // 只读表仅需getter方法 public function getCode(): string { return $this->code; } public function getSet(): int { return $this->set; } public function getLabel(): string { return $this->label; } }
步骤2:在Partner实体中配置带过滤条件的关联
在Partner实体的status和salutation字段上,使用@JoinColumns定义复合关联,固定set字段的匹配值:
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(readOnly=true) * @ORM\Table(name="partner") */ class Partner { // 映射partner表主键等基础字段 /** * @ORM\Id * @ORM\Column(name="partner_id", type="integer") */ private int $id; /** * @ORM\ManyToOne(targetEntity=Code::class) * @ORM\JoinColumns({ * @ORM\JoinColumn(name="status", referencedColumnName="code"), * @ORM\JoinColumn(referencedColumnName="set", value="1", insertable=false, updatable=false) * }) */ private ?Code $status = null; /** * @ORM\ManyToOne(targetEntity=Code::class) * @ORM\JoinColumns({ * @ORM\JoinColumn(name="salutation", referencedColumnName="code"), * @ORM\JoinColumn(referencedColumnName="set", value="2", insertable=false, updatable=false) * }) */ private ?Code $salutation = null; // 基础字段和关联字段的getter方法 public function getId(): int { return $this->id; } public function getStatus(): ?Code { return $this->status; } public function getSalutation(): ?Code { return $this->salutation; } }
配置说明
@JoinColumns定义了联合关联条件:第一个JoinColumn关联partner表的status/salutation字段到code表的code字段;第二个JoinColumn固定匹配code表的set字段值(1或2)。insertable=false, updatable=false标记该关联条件不可修改,适配外部只读表的特性。- 这样Doctrine在查询关联数据时,会自动生成包含
set = 1或set = 2的JOIN条件,确保获取到对应类型的正确label值。
内容的提问来源于stack exchange,提问作者cafce25
相关产品推荐
相关产品推荐

