【问题标题】:Doctrine findAll() does not find column when using addMetaResult使用 addMetaResult 时,学说 findAll() 找不到列
【发布时间】:2018-01-06 18:13:25
【问题描述】:

我将 Doctrine 和 ResultSetMappingBuilder 与 addMetaResult() 一起使用。 我在我的存储库中获得了本地查询,并映射到实体,它运行良好,代码结构如下:

 $rsm = new ResultSetMappingBuilder($entityManager);
 $rsm->addRootEntityFromClassMetadata('AppBundle\Entity\Example', 'e');
 $rsm->addFieldResult('e', 'id', 'id');
 $rsm->addMetaResult('e', 'value', 'value');

 $sql = "SELECT id, 5 as value FROM table";
 $query = $entityManager->createNativeQuery($sql, $rsm)
 $result = $query->getResult();

我的 entity.yml 看起来像这样:

AppBundle\Entity\Example:  
  ...
  fields:
     id:
        type: smallint
        nullable: false
        options:
            unsigned: true
        id: true
        generator:
            strategy: IDENTITY
     value:
       type: integer

但是当我在其他地方使用标准实体管理器方法时,像这样:

$this->exampleRepo->find(5);

然后我得到错误:

找不到列:1054“字段列表”中的未知列“t0.value”

这是因为我的表中没有真正的列“值”,它是元列。如果该列不在 Native Query 中,是否有任何配置跳过该列,或者如果它不存在则跳过,或者我必须覆盖存储库中的方法 find() 并在其中添加映射?

【问题讨论】:

    标签: php symfony doctrine-orm


    【解决方案1】:

    请查看this questionthis answerthis answer 以了解更多上下文。

    简短的回答是,您遇到了 Doctrine 的限制,因为您不能拥有看似是数据库列但不是的虚拟属性。所以当你把它添加到你的 entity.yml:

    value:
        type: integer
    

    您告诉 Doctrine 的是您的 Example 实体上有一个 value 列。因此,您尝试运行的任何 Doctrine 查询 except 都会中断。您的原始查询没有的原因是因为您正在运行本机查询并自己显式执行映射。

    所以你可能觉得你找到了解决 Doctrine 限制的方法,但你没有。

    最简单的解决方案是在您的示例实体中维护一个未映射的 value 字段,然后当您需要查询该字段时,只需将其添加到您的 Doctrine 查询中,然后手动设置您需要的内容.像这样的:

    $entityResults = [];
    
    /**
     * return array of arrays like: [
     *     ['example' => Example entity, 'value' => int value],
     *     ['example' => Example entity, 'value' => int value],
     * ]
     */
    $results = $em
        ->createQuery('SELECT e AS example, 5 AS value FROM AppBundle:Example')
        ->getResult();
    
    foreach ($results as $result) {
        $result['example']->setValue($result['value]);
        $entityResults[] = $result['example'];
    }
    
    return $entityResults;
    

    如果您想要更全球化的内容,可以考虑添加 custom hydrator

    【讨论】:

    • 是的,我做过类似的事情,但不是在 repo 中,而是在实体中,我在 getValue 方法而不是 sql 中进行计算,并且我在查询中根本不选择值。真正的查询非常庞大和复杂,所以我不想用 PHP 重写它,这就是我问这个问题的原因。但是您的回答对其他人有好处,所以我将其标记为正确:)
    • 听起来不错。您的方法适合您的情况,可能是最快的实施方式。
    猜你喜欢
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 2023-03-27
    • 2016-01-17
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    相关资源
    最近更新 更多