如何在没有连接列的情况下映射一对一关系(实体通过其ID进行连接)?

时间:2019-08-27 09:23:26

标签: php orm doctrine-orm doctrine mapping

在我的工作中,我试图用Doctrine映射旧数据库方案。我无法更改此方案,因为它已被其他公司应用程序使用。这是一个简短的方案概述:

表-global_register_item

ID | NAME                                      | DTYPE
1  | "global register item with article #1"    | law_regulation
2  | "global register item without article #1" | financial_reporter
3  | "global register item without article #2" | law_regulation
4  | "global register item without article #3" | law_regulation
5  | "global register item with article #2"    | financial_reporter

表格-文章

ID | SID | other fields which I actually do not need
1  | 89  | ...
5  | 45  | ...

表格-law_regulation

ID | other fields
1  | ...
3  | ...
4  | ...

表格-financial_reporter

ID | other fields
2  | ...
5  | ...

因此 global_register_item 是父级,并且 law_regulation financial_reporter 从该表继承。为了解决这个问题,我使用了class table inheritance,它工作正常。

问题是 global_register_item 文章之间的关系。这是一对一的关系,并通过其ID列完成关联(如果 global_register_item 中有一条与 article 相关的记录,则在中有一条记录>具有相同ID的文章表)。但是 global_register_item 中的某些记录在文章中没有记录。有什么办法可以将这种关系与学说相对应吗?

编辑1

这是我来自项目的PHP代码。顺便说一句。我只需要阅读记录。而且我需要将有关SID列的信息发送到我的GlobalRegisterItem实体。

GlobalRegisterItem类

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="global_register_item")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="DTYPE", type="string")
 * @ORM\DiscriminatorMap({
 *     "law_regulation" = "App\Entity\LawRegulation",
 *     "financial_reporter" = "App\Entity\FinancialReporter"})
 */
abstract class GlobalRegisterItem
{
    /**
     * @var int
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     */
    private $id;

    /**
     * @var string
     * @ORM\Column(name="name", type="string")
     */
     private $name;

     /**
      * Article|null
      * HOW TO MAP THIS?
      */
     private $article;
}

课堂文章

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="article")
 */
class Article
{
    /**
     * @var int
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     */
    private $id;

    /**
     * @var int
     * @ORM\Column(name="SID", type="int")
     */
     private $sid;
}

Class LawRegulation

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="law_regulation")
 */
class LawRegulation extends GlobalRegisterItem
{
    /** SOME MAPPED FIELDS */
}

FinancialReporter类

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="law_regulation")
 */
class FinancialReporter extends GlobalRegisterItem
{
    /** SOME MAPPED FIELDS */
}

2 个答案:

答案 0 :(得分:1)

您可以在Article实体中使用OneToOne bidirectional relation

/**
 * @ORM\OneToOne(targetEntity="GlobalRegisterItem", inversedBy="article")
 * @ORM\JoinColumn(name="id", referencedColumnName="id", nullable=true)
 */
private $item;

并在您的GlobalRegisterItem类中引用它:

 /**
  * Article|null
  * @ORM\OneToOne(targetEntity="Article", mappedBy="item")
  */
 private $article;

 /**
  * Gets the sid of the article (if any).
  * @returns int|null
  */
 public function getArticleSid()
 {
   if (null !== $this->article) {
     return $this->article->getSid();
   }
   return null;
 }

答案 1 :(得分:0)

一种解决此问题的可能方法(如果您只需要读取数据)是:

通过 global_register_item 文章

创建视图
SELECT global_register_item.*, article.SID AS `SID`
FROM global_register_item
LEFT JOIN article ON global_register_item.id = article.id

ID | NAME                                      | DTYPE              | SID
1  | "global register item with article #1"    | law_regulation     | 89
2  | "global register item without article #1" | financial_reporter | NULL
3  | "global register item without article #2" | law_regulation     | NULL
4  | "global register item without article #3" | law_regulation     | NULL
5  | "global register item with article #2"    | financial_reporter | 45

GlobalRegisterItem类

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="global_register_item_view")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="DTYPE", type="string")
 * @ORM\DiscriminatorMap({
 *     "law_regulation" = "App\Entity\LawRegulation",
 *     "financial_reporter" = "App\Entity\FinancialReporter"})
 */
abstract class GlobalRegisterItem
{
    /**
     * @var int
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     */
    private $id;

    /**
     * @var string
     * @ORM\Column(name="name", type="string")
     */
     private $name;

     /**
      * int|null
      * @ORM\Column(name="SID", type="integer")
      */
     private $sid;
}

我认为这远非最佳,但这是我能提出的最佳解决方案。