php - 2 个表与 Doctrine2 PHP 之间的双重关联

标签 php database postgresql doctrine-orm

我正在尝试将 5 个对象与 Doctrine2 (PHP) 关联起来。 我正在使用 PostgreSQL。

这是数据库架构: Database schema

一个公司可能有多个Hub,每个Hub有一个Harbor。 一个公司可能有很多Line,每个Line都有一个Linelist。 一个 Linelist 有 2 个港口。 例如,一个 Linelist 是“洛杉矶-西雅图”,多亏了 Line 表,多个公司可能拥有它。

我正在尝试查询一家公司的所有 Hub、Harbor、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);

因此,我只有与 harborstart_id 匹配的 LineList 和 Line 对象,但我想要匹配 harborstart_id 或 harborend_id 的对象。

你认为这在 DQL 中可行吗? 对于多对多,更改 Harbor 和 Linelist 之间的关系可能会更好?

最佳答案

我认为这是在您的实体中定义从 harborlinelist 的 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 将 Harbors 加入 LineLists(您将变量命名为 linelist,但我认为现在最好更改标识符,因为会有 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);

这应该会让您朝着正确的方向前进。如果它变得麻烦,那么您推测的多对多方法应该是一个有据可查的解决方案。

关于php - 2 个表与 Doctrine2 PHP 之间的双重关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8565125/

相关文章:

database - 人名查找/翻译

postgresql - 无法在 Dash 应用程序中根据 PostgreSQL 查询结果绘制图形

python - 调用 'createsuperuser' 时引发 UnicodeEncodeError

postgresql - 如何对表的列进行航位推算,postgresql

php - 如何在mysql中获取左表中的总记录和右表中的匹配记录

php新手: email library

database - Oracle 12c - 未插入记录的列默认字符串值 - 改为空

java - 使用 Hibernate 回调的优点?

php - Laravel 覆盖 EloquentUserProvider 以更改 validateCredentials() 中的密码字段名称

php - 在 PHP 中使用 VARBINARY 选择数据