Doctrine orm 使用原则2将鉴别器列映射到字段

Doctrine orm 使用原则2将鉴别器列映射到字段,doctrine-orm,Doctrine Orm,在我的项目中,我有以下几种: namespace MyProject\Model; /** * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */ class Person { // ... } /** @En

在我的项目中,我有以下几种:

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; }

    // ...
}

有没有一种方法可以让这在教义中起作用?或者我需要在entity to array方法中读取类元数据吗?

遗憾的是,没有文档化的方法将discr列映射到实体。这是因为discr列实际上是数据库的一部分,而不是实体

但是,将discr值直接放入类定义中是很常见的。它不会改变,不管怎样,你总是会得到相同值的相同类

class Person
{
    protected $discr = 'person';

class Employee extends Person
{
    protected $discr = 'employee';

您可以使用以下解决方案:

`$`$metadata = \Doctrine\ORM\Mapping\ClassMetadata((string)$entityName);
print_r($metadata->discriminatorValue);`

下面是我在一个ZF2项目(使用Doctrine MongoDB ODM)中的一个小例子:

//实体的实例
$实体=。。。;
/**@var\doctor\ODM\MongoDB\DocumentManager$DocumentManager*/
$documentManager=$serviceManager->get('documentManager');
/**@var\doctor\ODM\MongoDB\Mapping\ClassMetadataFactory$factory*/
$factory=$documentManager->getMetadataFactory()
/**@var\doctor\ODM\MongoDB\Mapping\ClassMetadata$metadata*/
$metadata=$factory->getMetadataFor(get_类($object));
如果($metadata->hasDiscriminator()){
//假设$data是上一次提取的结果
$data[$metadata->discriminatorField]=$metadata->discriminatorValue;
}
我所做的是实现了一个自定义接口
DiscriminatorAwareInterface
,我只对实现它的类应用检查(在您的例子中,它将是所有“discriminated”类扩展的类)

因此,我最终得到如下代码:

//将discrinimator字段的值添加到支持它的实体
if($DiscriminatorAwareInterface的对象实例){
/**@var\doctor\ODM\MongoDB\Mapping\ClassMetadata$metadata*/
$metadata=$factory->getMetadataFor(get_类($object));
如果($metadata->hasDiscriminator()){
$data[$metadata->discriminatorField]=$metadata->discriminatorValue;
}
}

我敢肯定,如果您使用标准ORM,情况也会一样,只是您将使用实体管理器而不是文档管理器。

刚刚解决了这个问题,但没有将鉴别器定义为真正的成员:

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 {}

可能与从
getMyDiscriminator()
读取discriminator Map的方法重复?当您需要在WHERE子句中访问您的鉴别器时,这没有帮助。
的实例有点类似,但这种数据掩蔽看起来非常奇怪(而且丑陋)对我来说。这只会带来复杂性和局限性,依我看。你可能没有抓住要点。只有条令才能访问鉴别器。你不能在DQL语句中访问它。的实例是DQL方法。是的,有很多局限性。但SQL本身不允许在单个列和多个表之间建立关系。如果有,那就好了。我很遗憾地注意到了这一点。我不明白的是,为什么条令不允许一个人获得这个值,这是非常有用的(无论是对于“where”,还是对于任何需要它的计算)。我只是在最近的一个开发中使用了这个特性,但我知道它对性能的影响,在限制之前做所有的连接(WHERE条款),并将字符串作为鉴别器键放在它们的示例中,这确实让我感到困惑。我的评论的重点是讲述
实例,因为条令使得这一点非常复杂。这里没有答案。你注意到日期了吗?我不确定条令早在2014年就有运算符实例。还有课程是关于访问鉴别器列的。不是查询。但无论您如何实现它,尝试将继承映射到sql数据库都是很尴尬的。我没有注意日期,只是想添加一个提示,因为这个问题可能在搜索结果中有一个很好的排名。无论如何,完全同意您的观点,并且不是为了b我只是想添加一些我认为有用的信息,但我在这里没有找到。