Php 如何选择原则2中的鉴别器列

Php 如何选择原则2中的鉴别器列,php,symfony,doctrine-orm,dql,discriminator,Php,Symfony,Doctrine Orm,Dql,Discriminator,我需要一些帮助,当运行下面的DQL时,从原则2中选择仅鉴别器列 SELECT p.type FROM AppBundle\Entity\Product p type是实体AppBundle\entity\Product @ORM\DiscriminatorColumn(name="type", type="smallint")` @ORM\DiscriminatorMap({ "0" = "AppBundle\Entity\Product", "1" = "AppBundle

我需要一些帮助,当运行下面的DQL时,从原则2中选择仅鉴别器列

SELECT p.type FROM AppBundle\Entity\Product p
type
是实体
AppBundle\entity\Product

@ORM\DiscriminatorColumn(name="type", type="smallint")`

@ORM\DiscriminatorMap({
    "0" = "AppBundle\Entity\Product",
    "1" = "AppBundle\Entity\Product\SingleIssue",
    "2" = "AppBundle\Entity\Product\CountBasedIssue",
    "3" = "AppBundle\Entity\Product\TimeBasedIssue"
})
我知道,
类型
在实体中不是不动产,但我是否可以这样做

提前谢谢

更新 在阅读了2天的条令代码之后,我决定重写SqlWalker并通过下面的代码片段创建新的代码

覆盖SqlWalker 最后一步 TL;博士 我知道这是一个非常复杂的解决方案(可能只是针对我的场景),所以我希望有人能给我另一个简单的方法来解决这个问题,非常感谢

我用这个小“黑客”

  • 为实体定义通用接口(可选但推荐)
  • 在此界面中创建一个
    getType
    方法
  • 在鉴别器实体中创建常量
  • 在每个被鉴别的实体内返回适当的常数
  • 这样,您就可以检索鉴别器“generic”实体(
    Product
    ,在您的例子中)并调用
    getType

    当然,如果您对直接由sql完成的结果过滤感兴趣,那么这根本不是一个解决方案,而且目前恐怕没有任何可用的解决方案。

    如果您发现比此更好的,请与我们分享。

    无法直接访问鉴别器列

    可能需要查询特殊类型的实体。 因为无法直接访问鉴别器列, 学说提供了建构的实例

    您可以使用DQL的
    实例查询实体的类型。例如:

    $query = $em->createQuery("SELECT product FROM AppBundle\Entity\AbstractProduct product WHERE product  INSTANCE OF AppBundle\Entity\Product");
    $products = $query->getResult();
    

    希望这有帮助

    您应该能够使用
    实例和
    案例的标量结果来完成此操作,当,(否则,)end
    子句:

    SELECT
      (case
         when p INSTANCE OF AppBundle\Entity\Product then \'0\'
         when p INSTANCE OF AppBundle\Entity\Product\SingleIssue then \'1\'
         when p INSTANCE OF AppBundle\Entity\Product\CountBasedIssue then \'2\'
         when p INSTANCE OF AppBundle\Entity\Product\TimeBasedIssue then \'3\'
         else \'foobar\'
       end) as type
    FROM
      AppBundle\Entity\Product p
    

    当然,缺点是每次添加
    DiscriminatorMap
    条目时都必须更新查询。

    是的,这是dql direct retrieve的正确答案。我注意到,即使在我的项目中,我也使用这种解决方案:)而且
    抽象公共函数getType()
    工作得很好(我的鉴别器实体也是抽象的)。虽然MAtteo使用
    实例的
    似乎是最干净的解决方案,但我的第一个想法是将鉴别器列加倍,其中一个原则不会掩盖。当然,这很难看,需要确保两个列都不能去同步,但它的优点是允许您对数据执行任何需要的操作。
    
    orm:
        ...
        hydrators:
            CustomHydrator: YourNamespace\To\CustomHydrator
    
    $query = $queryBuilder->getQuery();
    $query->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'YourNamespace\To\CustomSqlWalker');
    $query->setHint(\YourNamespace\To\CustomSqlWalker::FORCE_GET_DISCRIMINATOR_COLUMN, array($rootAlias)); // this alias will be used in CustomSqlWalker class
    $query->setHint(\YourNamespace\To\CustomSqlWalker::DISCRIMINATOR_CLASS_MAP, $this->getClassName()); // this full-qualify class name will be used in CustomHydrator class
    
    $products = $query->getResult('CustomHydrator');
    
    $query = $em->createQuery("SELECT product FROM AppBundle\Entity\AbstractProduct product WHERE product  INSTANCE OF AppBundle\Entity\Product");
    $products = $query->getResult();
    
    SELECT
      (case
         when p INSTANCE OF AppBundle\Entity\Product then \'0\'
         when p INSTANCE OF AppBundle\Entity\Product\SingleIssue then \'1\'
         when p INSTANCE OF AppBundle\Entity\Product\CountBasedIssue then \'2\'
         when p INSTANCE OF AppBundle\Entity\Product\TimeBasedIssue then \'3\'
         else \'foobar\'
       end) as type
    FROM
      AppBundle\Entity\Product p