Доктрина PHP: Полиморфные Ассоциации - PullRequest
0 голосов
/ 18 января 2011

Я использую Doctrine PHP ORM 2.0 .

Я хотел бы реализовать следующую иерархию классов.(Обратите внимание, что следующий фрагмент кода не будет выполнен, так как он не является ни синтаксически правильным PHP, ни правильным использованием аннотаций Doctrine.)

@MappedSuperclass
abstract class Location {}

@Entity
class GeoId {
  @Column(type = "float") $latitude;
  @Column(type = "float") $longitude;

  // this is the part that my question concerns
  @???
  $location; // any subclass of location can go here
}

Теперь для подклассов Location мы можем взять City, State и Country, например.Или Adress, если мы хотим быть очень конкретными.Для получения дополнительной информации об этой иерархии классов:

class Adress  { $parent; /* of type City, ... some other attributes */ }
class City    { $parent; /* of type State */ }
class State   { $parent; /* of type Country */ }
class Country {}

(Приведенная выше иерархия заставит мой ответ склониться к решению «Таблица на класс».)

Вопросы:

  1. Возможно ли иметь полиморфный атрибут в сущности, и если да, то как его реализовать?
  2. Какую стратегию наследования я могу реализовать в иерархии классов Location (как показано ниже),и какие стратегии являются предпочтительными (например, наследование MappedSuperclass, Single-Table или Class-Table)?

Ответы [ 3 ]

4 голосов
/ 18 января 2011

Возможно ли иметь полиморфный атрибут в сущности, и если да, как его реализовать?

Да, Doctrine 2 поддерживает три различных типа наследования: MappedSuperclass,Одиночная таблица и таблица класса ... как вы знаете. Справочник по доктринам объясняет, как их реализовать.

Вот хорошая статья, которую вы можете прочитать о сопоставлении наследования объектов: Отображение объектов в реляционных базах данных: подробное сопоставление O / R

0 голосов
/ 14 апреля 2015

Да, Doctrine 2 будет вызывать полиморфные ассоциации. Существуют проблемы с двунаправленными ассоциациями, использующими mappedBy и inversedBy, но простой случай работает нормально.

/** @Entity */
class GeoId {
  /** @Column(type = "float") */ 
  private $latitude;
  /** @Column(type = "float") */ 
  private $longitude;

  /** @OneToOne(targetEntity="Location") */ 
  private $location;
}
0 голосов
/ 20 января 2011

В этом случае вам потребуется наследование по одной или по таблице классов. Поскольку вы хотите запросить корень (Location), вам лучше использовать Single Table Inheritance из соображений производительности.

...