在我的项目中,我有几个class table inheritances这样:
namespace MyProject\Model;
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"person" = "Person", "employee" = "Employee"})
*/
class Person
{
// ...
}
/** @Entity */
class Employee extends Person
{
// ...
}
我有一种方法可以根据具有公共getter的字段将实体转换为数组。这里的问题是我丢失了数组中的继承信息,因为鉴别器值没有存储在字段中。
所以我尝试的是以下内容,希望学说会自动设置$disc
:
class Person
{
// can I automatically populate this field with 'person' or 'employee'?
protected $discr;
public function getDiscr() { return $this->discr; }
public function setDiscr($disc) { $this->discr; }
// ...
}
有没有办法让这项工作符合学说?或者我需要在实体到数组方法中读取类元数据吗?
答案 0 :(得分:17)
可悲的是,没有记录的方法将discrimin列映射到实体。那是因为discrimin列实际上是数据库的一部分,而不是实体。
但是,将discrimin值直接放在类定义中是很常见的。它不会改变,无论如何你总是得到相同的类。
class Person
{
protected $discr = 'person';
class Employee extends Person
{
protected $discr = 'employee';
答案 1 :(得分:3)
以下是我在一个ZF2项目中使用Doctrine MongoDB ODM的一个小例子:
// an instance of your entity
$entity = ...;
/** @var \Doctrine\ODM\MongoDB\DocumentManager $documentManager */
$documentManager = $serviceManager->get('DocumentManager');
/** @var \Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory $factory */
$factory = $documentManager->getMetadataFactory()
/** @var \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $metadata */
$metadata = $factory->getMetadataFor(get_class($object));
if ($metadata->hasDiscriminator()) {
// assuming $data is result of the previous extraction
$data[$metadata->discriminatorField] = $metadata->discriminatorValue;
}
我所做的是我已经实现了一个自定义接口DiscriminatorAwareInterface
,我只将检查应用于实现它的类(在你的情况下,它将是所有“有区别”类扩展的类。
结果我得到的代码如下:
// add value of the discrinimator field to entities that support it
if ($object instanceof DiscriminatorAwareInterface) {
/** @var \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $metadata */
$metadata = $factory->getMetadataFor(get_class($object));
if ($metadata->hasDiscriminator()) {
$data[$metadata->discriminatorField] = $metadata->discriminatorValue;
}
}
我很确定如果您使用标准ORM,它将是相同的,除了您将拥有实体经理的文档管理器。
答案 2 :(得分:2)
刚刚解决了这个问题而没有将鉴别器定义为真正的成员:
abstract class MyEntity {
const TYPE_FOO = 'foo';
const TYPE_BAR = 'bar';
const TYPE_BUZ = 'buz';
...
/**
* @return string
*/
public function getMyDiscriminator()
{
$myDiscriminator = null;
switch (get_class($this)) {
case MyEntityFoo::class:
$myDiscriminator = self::TYPE_FOO;
break;
case MyEntityBar::class:
$myDiscriminator = self::TYPE_BAR;
break;
case MyEntityBuz::class:
$myDiscriminator = self::TYPE_BUZ;
break;
}
return $myDiscriminator;
}
...
}
class MyEntityFoo extends MyEntity {}
class MyEntityBar extends MyEntity {}
class MyEntityBuz extends MyEntity {}
答案 3 :(得分:1)
您可以使用以下解决方案:
`$`$metadata = \Doctrine\ORM\Mapping\ClassMetadata((string)$entityName);
print_r($metadata->discriminatorValue);`