简体   繁体   English

教义映射到未知实体

[英]Doctrine mapping to unknow entity

is it possible to create a relation to a generic table/class whith Doctrine? 是否可以创建与通用表/类相关的准则?

Here is some code to make it easier to understand: 这是一些使它易于理解的代码:

// class Log...

// TODO:
// It could be useful to have a reference to
// the element mentioned by the log, the issue is
// we don't know what kind of entity it is.

/**
 * @ORM\ManyToOne(targetEntity="???")
 */
private $elementId

Maybe instead of using targetEntity I could just use an int that is the id of the element located in the unknow table. 也许不使用targetEntity而是使用int,它是位于unknow表中的元素的id。

You are trying to manage some abstraction of one or more of your entities in the database level which is a headache, 您正在尝试管理数据库级别中一个或多个实体的某种抽象,这令人头疼,

Doctrine already has proposed Somme solutions to manage this kind of abstractions by using Inheritance Mapping 主义已经提出了Somme解决方案,以通过使用继承映射来管理这种抽象。

A mapped superclass is an abstract or concrete class that provides persistent entity state and mapping information for its subclasses, but which is not itself an entity. 映射的超类是抽象类或具体类,它为其子类提供持久的实体状态和映射信息,但它本身并不是实体。 Typically, the purpose of such a mapped superclass is to define state and mapping information that is common to multiple entity classes. 通常,此类映射超类的目的是定义多个实体类共有的状态和映射信息。

For more information check this 有关更多信息,请检查

There is no built-in possibility now. 现在没有内置的可能性。

Let me propose a work around using Doctrine Lifecycle Events : 让我提出有关使用“ Doctrine生命周期事件”的工作的建议:

  • Create 3 properties : 创建3个属性:

     /* * @ORM\\Column(name="element_class", type="string") */ private $elementClass /* * @ORM\\Column(name="element_id", type="integer") */ private $elementId // Not mapped private $element public function setElement($element) { $this->element = $element; $this->elementClass = get_class($element); $this->elementId = $element->getId(); } public function getElement() { return $this->element; } // You need these for the PostLoad event listener : public function hydrateElementPostLoad($element) { $this->element = $element; } public function getElementClass() { return $this->elementClass; } public function getElementId() { return $this->elementId; } 
  • Then create a PostLoadListener able to hydrate the element property : 然后创建一个PostLoadListener,它可以使element属性水合:

     namespace AppBundle\\EventListener; use Doctrine\\ORM\\Event\\LifecycleEventArgs; use AppBundle\\Entity\\Log; class PostLoadListener { public function postLoad(LifecycleEventArgs $args) { $entity = $args->getEntity(); if($entity instanceOf Log){ $em = $args->getEntityManager(); $entity->hydrateElementPostLoad( $this->em->getRepository($entity->getElementClass())->findOneById($entity->getElementId()) ); } } } 
  • And register this event in your services.yml : 并在您的services.yml中注册此事件:

     services: places.listener: class: AppBundle\\EventListener\\PostLoadListener tags: - { name: doctrine.event_listener, event: postLoad } 

That's also how the most famous Bundle for logging works ( The Gedmo DoctrineExtensions Logger ) 这也是最著名的日志记录捆绑软件的工作方式( The Gedmo DoctrineExtensions Logger

  • To retrieve all logs for an entity, create a repository method for your Log entity : 要检索一个实体的所有日志,请为您的Log实体创建一个存储库方法:

     getLogs($entity) { return $this->_em->findBy(array( 'element_id'=>$entity->getId(), 'element_class'=>get_class($entity) )); } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM