Doctrine 2中的多态关联

11

有没有一种方法能在Doctrine中实现Laravel的多态关系?

以下是一个示例:

class Address
{
    protected $street;
    ...

    public function setStreet()
    {

    }

    public function getStreet()
    {

    }
}

class Event
{
    /*one to many*/
    protected $addresses;
    ...
}

class Museum
{
    /*one to many*/
    protected $addresses;
    ...
}

在数据库中,它会是这样的:

Address:
    id | type (event or museum) | type_id | street ...

Event:
    id | name ...

Museum:
    id | name ...

我看了一下单表继承,它似乎可以解决我的问题,但我不知道如何将事件或博物馆与地址相关联。如果有人能 ELI5(用通俗易懂的语言解释),我将不胜感激。

1个回答

9

看起来这似乎是继承映射的用例,除非您有大量不同类型的实体要存储地址。使用Doctrine中的示例,您将为每个地址创建两个类。

<?php
namespace MyProject\Model;

/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({"event" = "EventAddress", "museum" = "MuseumAddress"})
 */
class Address {
    protected $street;
    // ...
}

/**
 * @Entity
 */
class EventAddress extends Address {
    protected $event;
    // ...
}

/**
 * @Entity
 */
class MuseumAddress extends Address {
    protected $museum;
    // ...
}

阅读有关继承映射的更多信息。


$event和$museum会是关联吗?就像这样: @ORM\ManyToOne(targetEntity="Event", inversedBy="addresses")protected $event; - Diego Castro
1
是的,没错。在数据库中,一个EventAddress将会有一个空的museum_id字段,而一个MuseumAddress将会有一个空的event_id字段。 - Peter
非常感谢!我曾经费尽心思地试图理解继承映射,但现在我认为我已经清楚地了解了它的工作原理。 - Diego Castro
EventAddress和MuseumAddress在ORM的角度来看是不同的实体,因此您需要直接引用它们进行关联。例如,对于我们的Museum类上的'address'属性,我们将使用以下注释:@ORM\OneToMany(targetEntity="MuseumAddress", inversedBy="museum") - Peter
1
我已经很久没有写PHP了,但总的来说,这种解决方案现在对我来说似乎是错误的方法,特别是在像多对多多态继承这样复杂的情况下。继承映射闻起来像是将数据库模式硬耦合到对象图中,这是对RDBMS的滥用。这个答案比我更好地解释了这个问题,这已经是多年前使用ORM(如Doctrine)的事情了。这篇博客文章也提供了一些有用的想法。 - Peter
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接