我的多对多关系定义如下:
两个相关表:
CREATE TABLE `homily` (
`homilyID` int NOT NULL AUTO_INCREMENT,
`homily` text NOT NULL,
PRIMARY KEY (`homilyID`),
) ENGINE=InnoDB
CREATE TABLE `liturgy` (
`liturgyID` int NOT NULL AUTO_INCREMENT,
`timeFK` tinyint NOT NULL,
`typeFK` tinyint NOT NULL,
`week` tinyint NOT NULL,
`day` tinyint NOT NULL,
`colorFK` tinyint NOT NULL,
`name` varchar(200) COLLATE utf8mb3_spanish_ci NOT NULL,
PRIMARY KEY (`liturgyID`),
UNIQUE KEY `timeFK` (`timeFK`,`typeFK`,`week`,`day`),
KEY `colorFK` (`colorFK`)
) ENGINE=InnoDB
以及处理多对多关系的中间表:
CREATE TABLE `liturgy_homily_join` (
`liturgyFK` int NOT NULL,
`homilyFK` int NOT NULL,
`theme` varchar(200) COLLATE utf8mb3_spanish_ci NOT NULL DEFAULT '',
PRIMARY KEY (`liturgyFK`,`homilyFK`),
KEY `homilyFK` (`homilyFK`),
CONSTRAINT `liturgy_homily_join_ibfk_1` FOREIGN KEY (`liturgyFK`) REFERENCES `liturgy` (`liturgyID`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `liturgy_homily_join_ibfk_2` FOREIGN KEY (`homilyFK`) REFERENCES `homily` (`homilyID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
现在我想使用条件查询我的
liturgy
表并获取所有相关的 homily
行。
为此,我尝试在 Liturgy
班级看起来像这样:
Liturgy
namespace App\Entity;
use App\Repository\LiturgyRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: LiturgyRepository::class)]
class Liturgy
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(name:"liturgyID")]
private ?int $id = null;
#[ORM\Column(type: Types::SMALLINT, name:"timeFK")]
private ?int $timeFK = null;
#[ORM\Column(type: Types::SMALLINT)]
private ?int $week = null;
#[ORM\Column(type: Types::SMALLINT)]
private ?int $day = null;
#[ORM\Column(length: 200)]
private ?string $name = null;
#[ORM\Column(type: Types::SMALLINT, name:"typeFK")]
private ?int $typeFK = null;
#[JoinTable(name: 'liturgy_homily_join')]
#[JoinColumn(name: 'liturgyFK', referencedColumnName: 'id')]
#[InverseJoinColumn(name: 'homilyFK', referencedColumnName: 'id')]
#[ManyToMany(targetEntity: Homily::class)]
public ?Collection $homilies=null;
public function __construct()
{
$this->$homilies = new ArrayCollection();
}
public function getHomilies(): ?Collection
{
return $this->homilies;
}
public function getId(): ?int
{
return $this->id;
}
// ...
}
我还尝试了双向多对多关系,正如文档所解释的这里。
在这种情况下,类看起来像这样:
Liturgy
namespace App\Entity;
use App\Repository\LiturgyRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: LiturgyRepository::class)]
class Liturgy
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(name:"liturgyID")]
private ?int $id = null;
#[ORM\Column(type: Types::SMALLINT, name:"timeFK")]
private ?int $timeFK = null;
#[ORM\Column(type: Types::SMALLINT)]
private ?int $week = null;
#[ORM\Column(type: Types::SMALLINT)]
private ?int $day = null;
#[ORM\Column(length: 200)]
private ?string $name = null;
#[ORM\Column(type: Types::SMALLINT, name:"typeFK")]
private ?int $typeFK = null;
/*
#[JoinTable(name: 'liturgy_homily_join')]
#[JoinColumn(name: 'liturgyFK', referencedColumnName: 'id')]
#[InverseJoinColumn(name: 'homilyFK', referencedColumnName: 'id')]
#[ManyToMany(targetEntity: Homily::class)]
*/
#[ManyToMany(targetEntity: Homily::class, inversedBy: 'liturgies')]
#[JoinTable(name: 'liturgy_homily_join')]
public ?Collection $homilies=null;
public function __construct()
{
$this->$homilies = new ArrayCollection();
}
public function getHomilies(): ?Collection
{
return $this->homilies;
}
public function getId(): ?int
{
return $this->id;
}
public function getLiturgyID(): ?int
{
return $this->id;
}
public function setLiturgyID(int $liturgyID): static
{
$this->id = $liturgyID;
return $this;
}
public function getTimeFK(): ?int
{
return $this->timeFK;
}
public function setTimeFK(int $timeFK): static
{
$this->timeFK = $timeFK;
return $this;
}
public function getWeek(): ?int
{
return $this->week;
}
public function setWeek(int $week): static
{
$this->week = $week;
return $this;
}
public function getDay(): ?int
{
return $this->day;
}
public function setDay(int $day): static
{
$this->day = $day;
return $this;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
public function getTypeFK(): ?int
{
return $this->typeFK;
}
public function setTypeFK(int $typeFK): static
{
$this->typeFK = $typeFK;
return $this;
}
}
Homily
namespace App\Entity;
use App\Repository\HomilyRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: HomilyRepository::class)]
class Homily
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(name:'homilyID')]
private ?int $id = null;
#[ORM\Column(type: Types::TEXT)]
private ?string $homily = null;
#[ManyToMany(targetEntity: Liturgy::class, mappedBy: 'homilies')]
private Collection $liturgies;
public function __construct() {
$this->liturgies = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getHomily(): ?string
{
return $this->homily;
}
public function setHomily(string $homily): static
{
$this->homily = $homily;
return $this;
}
}
我的问题是,在这两种情况下,代码都不起作用。假设这段代码在
LiturgyRepository
:
public function findHomily(string $time,string $week,string $day,string $cycle): ?array
{
$timeFK=$this->timeAssoc[$time] ?? null;
$day=$this->dayAssoc[$day] ?? null;
$cycle=$this->cycleAssoc[$cycle] ?? null;
$qb= $this->createQueryBuilder('liturgy')
->andWhere('liturgy.id > 0')
/* quitamos criterios de parámetros por el momento*/
->setMaxResults(5)
->getQuery()
->getResult()
;
dd($qb);
return $qb;
}
如果我理解正确,如果关系有效,我应该在
homilies
属性中包含 Homily
对象列表,但我总是得到 null
,正如您在调试中看到的:
0 => App\Entity\Liturgy {#651 ▼
-id: 1
-timeFK: 1
-week: 1
-day: 1
-name: "Domingo I de Adviento (Año A)."
-typeFK: 1
+homilies: null
}
1 => App\Entity\Liturgy {#649 ▼
-id: 2
-timeFK: 1
-week: 2
-day: 1
-name: "Domingo II de Adviento (Año A)."
-typeFK: 1
+homilies: null
我澄清这不是数据的问题,表在这些关系中有匹配的记录。例如查询:
select
h.homilyID
from liturgy l
inner join liturgy_homily_join j
on l.liturgyID=j.liturgyFK
inner join homily h
on j.homilyFK=h.homilyID
where
l.liturgyID=1;
它给了我满足关系的所有行:
+----------+
| homilyID |
+----------+
| 1987 |
| 1989 |
| 1990 |
| ... |
+----------+
谁能告诉我在建立关系方面我犯了什么错误?
这里有一些问题!
首先,我更喜欢具有尽可能少属性的双向关系 - 您在第二个示例中显示的映射似乎不错(您可以验证学说是否满意
php bin/console doctrine:schema:validate
)
你的构造函数是错误的,并且将 ArrayCollection 属性赋予了错误的变量
public function __construct()
{
// Remove the $ in front of homilies !
$this->homilies = new ArrayCollection();
}
那么你应该知道,集合默认是惰性的(在你尝试使用它们之前它们是未填充的)。所以只是“倾倒”你的礼拜结果不会让他们看到。
您可以通过循环检查是否有必要的结果
foreach($liturgy->getHomilies() as $homily) {...}
或者通过计数
$liturgy->getHomilies()->count()