【问题标题】:Double association between 2 tables with Doctrine2 PHP2个表与Doctrine2 PHP之间的双重关联
【发布时间】:2012-01-23 19:22:25
【问题描述】:

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

这是数据库架构: Database schema

一家公司可能有很多 Hub,每个 Hub 有一个 Harbor。 一个公司可能有很多 Line,每条 Line 都有一个 Linelist。 一个 Linelist 有 2 个港口。 例如,Linelist 是“Los Angeles-Seattle”,由于 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);

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

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

【问题讨论】:

    标签: php database postgresql doctrine-orm


    【解决方案1】:

    我认为这是在您的实体中定义从 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);
    

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

    【讨论】:

    猜你喜欢
    • 2023-03-16
    • 1970-01-01
    • 2014-01-15
    • 2014-07-01
    • 2019-12-17
    • 2021-06-29
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多