我正在尝试使用Doctrine2(PHP)对5个对象进行关联。 我正在使用PostgreSQL。
这是数据库架构: Database schema
公司可能有许多枢纽,每个枢纽都有一个港口。 一家公司可能有很多Line,每行都有一个Linelist。 Linelist有2个Harbour。 例如,Linelist是“洛杉矶 - 西雅图”,由于Line表,多家公司可能拥有它。
我正在尝试查询一家公司的所有Hub,Harbour,Linelist和Line。 我有SQL查询:
SELECT *
FROM hub h
JOIN harbor a
ON a.id = h.harbor_id
JOIN linelist l
ON (l.harborstart_id = a.id OR l.harborend_id = a.id)
JOIN line m
ON m.linelist_id = l.id
WHERE h.company_id = 41
AND m.company_id = 41"
我正在尝试使用DQL做同样的事情。 我尝试过这个,但它不起作用:
$query = $this->getEntityManager()
->createQuery('SELECT h, a, l, m
FROM AmGameBundle:Hub h
JOIN h.harbor a
JOIN a.linelist l
JOIN l.line m
WHERE h.company = :company_id
AND m.company = :company_id')
->setParameter('company_id', $company_id);
因此,我只将LineList和Line对象与harborstart_id匹配,但我希望匹配harborstart_id或harborend_id。
您认为这在DQL中是否可行? 对于多对多人来说,更改港口和航线列表之间的关系可能会更好吗?
答案 0 :(得分:0)
我认为这是在您的实体中定义从 harbour 到 linelist 的2个关系的问题。我想你有类似
的东西<?php
/**
* @Entity
* @Table(name="LineList")
*/
class LineList {
/**
* @var object $startHarbor
* @ManyToOne(targetEntity="Harbor", inversedBy="startHarbors")
* @JoinColumn(name="harborstart_id", referencedColumnName="id", nullable=FALSE)
*/
protected $startHarbor;
}
/**
* @Entity
* @Table(name="Harbor")
*/
class Harbor {
/**
* @var object $startHarbors
* @OneToMany(targetEntity="LineList", mappedBy="startHarbor")
*/
protected $startHarbors;
}
这样您就可以通过 harborstart_id (您将变量命名为 linelist )将Harbors加入LineLists,但我认为现在最好更改标识符,因为会有2个引用到同一个外国表),然后如果你想 harborend_id
<?php
/**
* @Entity
* @Table(name="LineList")
*/
class LineList {
/**
* @var object $startHarbor
* @ManyToOne(targetEntity="Harbor", inversedBy="startHarbors")
* @JoinColumn(name="harborstart_id", referencedColumnName="id", nullable=FALSE)
*/
protected $startHarbor;
/**
* @var object $endHarbor
* @ManyToOne(targetEntity="Harbor", inversedBy="endHarbors")
* @JoinColumn(name="harborend_id", referencedColumnName="id", nullable=FALSE)
*/
protected $endHarbor;
}
/**
* @Entity
* @Table(name="Harbor")
*/
class Harbor {
/**
* @var object $startHarbors
* @OneToMany(targetEntity="LineList", mappedBy="startHarbor")
*/
protected $startHarbors;
/**
* @var object $endHarbors
* @OneToMany(targetEntity="LineList", mappedBy="endHarbor")
*/
protected $endHarbors;
}
现在您可以将DQL更改为:
$query = $this->getEntityManager()
->createQuery('SELECT h, a, sh, eh, m
FROM AmGameBundle:Hub h
JOIN h.harbor a
JOIN a.startHarbors sh
JOIN a.endHarbors eh
JOIN l.line m
WHERE h.company = :company_id
AND m.company = :company_id')
->setParameter('company_id', $company_id);
这应该让你朝着正确的方向前进。如果它变得麻烦,你推测的多对多方法应该是一个记录良好的解决方案。