【问题标题】:Doctrine 2 - One-to-Many unidirectional原则 2 - 一对多单向
【发布时间】:2014-07-21 20:22:21
【问题描述】:

关于在 Doctrine 2 中创建一对多单向关系的几个问题:

  1. 是否需要连接表?
  2. docs 说“看看这个例子”,但我看到的只是生成的模式。有人介意快速举个例子,这样我就可以正确注释了吗?

【问题讨论】:

  • 您可以尝试不使用@JoinTable 注释并报告它是否正常工作吗?

标签: php symfony doctrine-orm


【解决方案1】:

您使用的是 2.0.x 版本的文档。检查this one。你会有例子。

所以是的,您可以避免在两个类之一中使用注释。

【讨论】:

  • 您可以在不使用连接表的情况下建立一对多关系
  • 为什么 OnetoMany 单向的示例显示的是 ManyToMany?
  • @Scott 虽然这是正确的答案,但应该添加一些进一步的解释来解释多对多。其中一张表应保存另一张表的行 ID。但是在一对多的情况下,我们只有一行,不能分配所有的 id。所以我们创建了一个 ManyToMany,它创建了另一个表来为我们保存这个映射。现在要锁定 OneToMany 概念,我们在新表的 inverseJoinColumns 上创建一个唯一索引。
【解决方案2】:

这展示了一对多的关系,一个用户可以有多个报告,而一个报告只能属于一个用户。

class User
{
    // ...

    /**
     * @OneToMany(targetEntity="Report", mappedBy="user")
     */
    protected $reports;

    public function __construct()
    {
        $this->reports = new ArrayCollection();
    }

    public function addReport(\Namespace\To\Report $report)
    {
        $this->report[] = $report;
    }

    public function getReports()
    {
        return $this->reports;
    }
}

class Report
{
    // ...

    /**
     * @ManyToOne(targetEntity="User", inversedBy="reports")
     * @JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

    public function setUser(\Namespace\To\User $user)
    {
        $this->user = $user;
    }

    public function getUser()
    {
        return $this->user;
    }
}

在这种情况下,要创建报告并将其与用户关联,我们将:

// create a User (or find an existing one)
$user = new User();
// create the Report
$report = new Report();
// add the User to the Report
$report->setUser($user);
// then persist it, etc ...

【讨论】:

  • 他要求单向关联。另外,如果我没记错的话,Doctrine 只会检查拥有方(Report::user),所以你的第二个 sn-p 将不起作用。
  • 根据 Doctrine 文档,一对多关系必须是双向的,除非您使用连接表。因此,根据 OP 的要求,这提供了连接表的替代方案。但是,我不知道不能调用 add->report() 。如果是这样的话,Symfony 生成这些方法似乎很奇怪......
  • 好吧,我没有很好地理解这个主题。我正在考虑 DBMS 中的连接表。如果他谈论注释,那么,是的,他将需要它,但我再次不确定,我需要尝试一下。 -- addReport 可以被调用,但我认为它会抛出一个异常,说 Doctrine 找到了一个没有自动持久化的新实体,否则它不会看到它。只是因为学说只使用关联的拥有方,而 User::report 是反方。
  • 如果你想让我删除 -1 只需编辑你的答案(只是一点点:D)(所以限制。不要改变任何东西,只需添加一些东西)
  • 已删除最终的 sn-p。如果需要其他编辑,请更新,我很乐意学习
【解决方案3】:

不,不是。试试这个:

class Foo
{
    public function __construct()
    {
        $this->bars = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * @ORM\OneToMany(targetEntity="My\AwesomeBundle\Entity\Bar", mappedBy="foo")
     */
    protected $bars;
}

class Bar
{
    /**
     * @ORM\ManyToOne(targetEntity="My\AwesomeBundle\Entity\Foo", inversedBy="bars")
     */
    protected $foo;
}

【讨论】:

  • 我尽量避免我的Bars 必须了解Foo。如果不是,那就这样吧,但我希望找到一种方法来实现这一点
  • 好吧,我认为您可以在此处省略注释,但如果我是正确的,那么关系将不会是单向的。如果您因为捆绑包之间的耦合丢失而不想这样做,请查看resolve_target_entities
【解决方案4】:

这适用于 Doctrine 2 + Zend Framework 2.5,同时获取一对多 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional

在我的情况下,我必须检索产品及其文档(每个产品至少 5 个文档)

ArrayCollection 本身做得很好。

在查看器中,您只需 foreach 对象 Product,然后再一次 foreach $product->getDoc() 就可以了。

【讨论】:

    【解决方案5】:

    我参加聚会有点晚了,但我就是这样做的:

    <entity name="User" table="users">
        <id name="id" type="integer" column="id">
          <generator strategy="IDENTITY"/>
        </id>
    
        <one-to-many field="children" target-entity="User" mapped-by="father">
        </one-to-many> 
    
        <many-to-one field="father" target-entity="User" inversed-by="children">
            <!-- without this row it doesn't work -->
            <join-column name="id" referenced-column-name="id" />
        </many-to-one>
    </entity>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 2014-05-23
      相关资源
      最近更新 更多