Доступ к отношениям таблицы с наследованием - PullRequest
3 голосов
/ 02 июля 2011

У меня есть класс наследования, как показано здесь:

Relations

Как вы можете легко видеть у пользователей, здания и отели имеют адреса (более одного), а в таблице адресов хранится идентификатор владельца, в столбце которого

.
  1. Правильна ли моя логика?
  2. Допустим, я хочу получить адрес пользователя (или здания или гостиницы), чей идентификатор равен 2; я должен выполнить оператор DQL (и как?) или я могу получить его с помощью функции find() без DQL?

И я буду рад, если вы приведете пример, поскольку документация по Doctrine не очень помогает.

Спасибо.

Редактировать: пользователи, здания и отели являются просто символическими именами, поэтому они могут иметь несколько адресов, иначе здания и отели будут иметь только один адрес.

Редактировать 2 : Я думаю, что не смогу прояснить ситуацию, когда я говорю о наследовании таблиц классов. Я имею в виду, что для класса сущностей столбец Discriminator имеет значение

/**
 * ...
 *
 * @DiscriminatorColumn(name="classname", type="string")
 * @DiscriminatorMap({"Entities\users" = "Entities\users",
 * "Entities\buildings" = "Entities\buildings"}) ... etc
 */

Каждый подкласс связан с parent (Entity) с отношением внешнего ключа как "id". Но, конечно, доктрина создает эту связь уже для меня.

Ответы [ 3 ]

1 голос
/ 02 июля 2011

Обычно адрес - это типичный объект значения .Объекты-значения обычно хранятся вместе с сущностью, составляющей объект-значение, поэтому речь идет не об отношениях или наследовании таблиц классов.Если в вашем домене указано иное (например, вы можете сделать что-то со своим адресом, что означает), они могут быть сущностью, тогда как сущность Hotel содержит сущность Address (сохраняется в таблице отношений: m) и сущность Building удерживаетсяи Address тоже (в другой таблице отношений n: m).

Если вы пойдете по маршруту объекта значения, все будет иначе.Вы должны хранить адрес как с сущностью Building, так и с сущностью Hotel (как вы это делаете с другими объектами-значениями, например, Money или Email или Password).Так что вам вообще не нужны отношения, просто еще несколько полей.Проблема с Doctrine 2 заключается в том, что он не поддерживает сопоставление компонентов .Компонентное сопоставление будет использоваться для удобного хранения объектов-значений.То же самое можно сделать с Doctrine 2, вы бы реализовали обработчик @prePersist и @postLoad следующим образом:

class Hotel
{
    private ;

    /** These fields are persisted */

    /** @Column(type=string) */
    private $addressStreet;
    /** @Column(type=string) */
    private $addressCity;
    /** @Column(type=string) */
    private $addressZip;
    /** @Column(type=string) */
    private $addressCountry;

    /** @prePersist */
    public function serializeValueObjects()
    {
        $this->addressStreet = ->address->getStreet();
        $this->addressCity = ->address->getCity();
        $this->addressZip = ->address->getZip();
        $this->addressCountry = ->address->getCountry();
    }


    public function unserializeValueObjects()
    {
        $this->address = new Address(->addressStreet, ->addressCity, ->addressZip, ->addressCountry);
    }
}

Поскольку вам нужно сериализовать / десериализовать объекты значений Address в разных местах,Возможно, вы захотите извлечь сериализованный код в отдельный класс.

1 голос
/ 01 августа 2011
/**
 *
 * @Entity
 * @Table(name="proposaltemplate")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="entitytype", type="string")
 * @DiscriminatorMap({"proposal" = "ProposalTemplate","page" = "PageTemplate"})
 *
 */

abstract class AbstractProposalTemplate
{
    /**
     *
     * @var integer
     * @Id
     * @Column(type="integer")
     * @generatedValue(strategy="AUTO")
     *
     */
    private  $id;
}

next

@Entity 

class ProposalTemplate extends AbstractProposalTemplate
{

      @Id
      @Column(type="integer")
      @generatedValue(strategy="AUTO")


    private  $id;

}
next another class

  @Entity

class PageTemplate extends AbstractProposalTemplate
{
   /**
     *
     * @var integer
     * @Id
     * @Column(type="integer")
     * @generatedValue(strategy="AUTO")
     *
     */
    private  $id;
}
0 голосов
/ 02 июля 2011

Итак, у вас есть суперкласс под названием «Entity», у которого есть подклассы «Пользователь», «Здание» и «Отель».

Ваша сущность "Entity" должна иметь отношение OneToMany к Address. Давайте представим, что это выглядит так в вашем определении сущности:

/**
 * @OneToMany(targetEntity="Address", mappedBy="whose"
 */
protected $addresses;

Это более или менее хороший подход, хотя использование наследования немного вонючее.

Тогда, если вы хотите перебрать адреса внутри пользователя, здания или гостиницы:

foreach($this->addresses as $address){
    //do something with adderess
}

Это отвечает на ваш вопрос?

...