在我的项目中,我有几个类表的继承:
namespace MyProjectModel;
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"person" = "Person", "employee" = "Employee"})
*/
class Person
{
// ...
}
/** @Entity */
class Employee extends Person
{
// ...
}
我有一种方法,该方法将实体转换为基于具有公共getters的字段。这里的问题是我在数组中丢失了继承信息,因为鉴别值未存储在字段中。
所以我尝试的是以下内容,希望学说能自动设置$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; }
// ...
}
有没有办法在学说中进行这项工作?还是我需要阅读我的实体到阵列方法中的类元数据?
可悲的是,没有任何记录的方法将ist列映射到实体。这是因为iND列实际上是数据库的一部分,而不是实体。
但是,直接将DICT值直接放在类定义中是很常见的。它不会改变,无论如何,您总是会获得相同值的同一类。
class Person
{
protected $discr = 'person';
class Employee extends Person
{
protected $discr = 'employee';
这是我在ZF2项目之一(使用Doctrine MongoDB ODM)中拥有的一个小例子:
// an instance of your entity
$entity = ...;
/** @var DoctrineODMMongoDBDocumentManager $documentManager */
$documentManager = $serviceManager->get('DocumentManager');
/** @var DoctrineODMMongoDBMappingClassMetadataFactory $factory */
$factory = $documentManager->getMetadataFactory()
/** @var DoctrineODMMongoDBMappingClassMetadata $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 DoctrineODMMongoDBMappingClassMetadata $metadata */
$metadata = $factory->getMetadataFor(get_class($object));
if ($metadata->hasDiscriminator()) {
$data[$metadata->discriminatorField] = $metadata->discriminatorValue;
}
}
我敢肯定,如果您使用标准ORM,那将是相同的,除非您将拥有Entity Manager。
刚解决了这个问题,并在不定义歧视者为真实成员的情况下解决了这个问题:
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 {}
您可以使用以下解决方案:
`$`$metadata = DoctrineORMMappingClassMetadata((string)$entityName);
print_r($metadata->discriminatorValue);`