Doctrine orm Doctrine的createQueryBuilder是否绕过实体getter方法?

Doctrine orm Doctrine的createQueryBuilder是否绕过实体getter方法?,doctrine-orm,twig,symfony,Doctrine Orm,Twig,Symfony,我对Symfony很陌生,有科哈纳的背景,我很难适应这个教条 目前我有一个product表,我正在使用createQueryBuilder内部连接一些其他表,需要在产品实体的getter方法中添加一些额外的逻辑。然而,看起来getter方法甚至没有被使用。以下是我的一些代码片段: //From AppBundle\Controller\ProductController $repository = $this->getDoctrine()->getRepository('AppBu

我对Symfony很陌生,有科哈纳的背景,我很难适应这个教条

目前我有一个product表,我正在使用createQueryBuilder内部连接一些其他表,需要在产品实体的getter方法中添加一些额外的逻辑。然而,看起来getter方法甚至没有被使用。以下是我的一些代码片段:

//From AppBundle\Controller\ProductController

$repository = $this->getDoctrine()->getRepository('AppBundle:Product');
$products = $repository->findWithLimitNew(24);

//From AppBundle\Repositories\ProductRepository
public function findWithLimitNew($limit=1)
{
    $em = $this->getEntityManager();
    $qb = $em->createQueryBuilder();
    $qb->select( 'p.name', 'p.id', 'p.slug', 'pc.name AS catname' )
        ->from('AppBundle\Entity\Product', 'p')
        ->innerJoin(
            'AppBundle\Entity\ProductAttributes',
            'pa',
            \Doctrine\ORM\Query\Expr\Join::WITH,
            'p.id = pa.productId'
        )
        ->innerJoin(
            'AppBundle\Entity\ProductCategories',
            'pc',
            \Doctrine\ORM\Query\Expr\Join::WITH,
            'pa.value = pc.id'
        )
        ->where('pa.type = 1')
        ->where('pa.default = 1')
        ->setMaxResults($limit);

    return $qb->getQuery()->getResult();
}

// From AppBundle\Entity\Product
/**
 * Get name
 *
 * @return string
 */
public function getName()
{
    #return $this->name; //<--Commenting this out for now
    return 'Some stupid string';
}

// From index.twig.html
{% for product in products %}
<h1>{{product.name}}</h1>
{% endfor %}

现在您可以看到,getter方法getName返回了一个字符串,但是当呈现视图时,我得到的是产品名称,而不是返回的字符串。有什么好处?

@Cerad有道理。乍一看,您的查询看起来像是DQL而不是QB。但是现在我意识到您的代码是正确的,您可以简化QueryBuilder QB代码:

$qb->select( 'p' )
  ->from('AppBundle:Product', 'p')
  ->innerJoin(
        'AppBundle:ProductAttributes',
        'pa',
        'WITH',
        'p.id = pa.productId'
  )
  ->innerJoin(
        'AppBundle:ProductCategories',
        'pc',
        'WITH',
        'pa.value = pc.id'
  )
  ->where('pa.type = 1')
  ->andWhere('pa.default = 1')
  ->setMaxResults($limit);
请注意,我使用了andWhere,但您的原始版本有一个额外的where。我很惊讶这是有效的,没有抛出和错误

另外,我认为主要的问题是,您只需要了解返回的结果。然后在细枝中,不调用属性,而是调用getter,如下所示:

// From index.twig.html
{% for product in products %}
    <h1>{{ product.getName }}</h1>
{% endfor %}
你能试试这些变化吗?我认为在细枝模板中调用getter是个问题


这可能行不通。如果没有,请告诉我们。

正如您所怀疑的,当水合实体(即从数据库检索)时,原则2使用反射直接设置实体属性。包括构造函数在内的所有方法都将被忽略。DQL不是SQL。我很惊讶你的查询竟然返回了任何东西。@Cerad我的查询来自于一个条令网站,查询工作正常。当然,我用我的表名进行了修改。AppBundle\Entity\Product中的名称字段是否标记为pubic?如果是这样的话,那可能是因为twig看到该属性是公共的,而没有费心调用getter。尝试将其设置为私有并将getter保留为public如果所有关系都已映射,则只需要innerJoin'p.attributes','pa'。无需详细说明内容,也无需指定产品属性类。我明白@Cerad的意思,我完全同意您的意见,因此同意upvote。这个op对Symfony来说是新的,我只是假设他的查询是这样工作的。只是想帮助解决这个问题。一旦他熟悉了“更简单”的方法,他就可以改变他的设计了。@AlvinBunk,当我尝试更改为{{product.getName}时,甚至在函数中添加了括号,我得到了可怕的数组到字符串转换错误。从我的理解来看,product.name实际上应该调用getter getName,但在这种类型的查询中,正如Cerad所说,它直接将结果水合到数组中,而不使用getter。由于传递给我的要求,product images表不包括图像的路径,只有图像名称。这些图像来自已爬网的站点,需要根据它们的爬网位置将它们保存在不同的目录中。因此,一个简单的关系是不可能的,因为我需要检查图像从何处爬网,并为它们构造一个路径,然后附加图像名称。似乎与教义无关。爱ORM的,但他们可能太严格了。这就是为什么我如此喜欢Kohana,它的数据库对象更松散。实际上,pogeybait,你能在开发环境的小枝中做一个dumpproduct.getName,然后发布结果吗。我想看看它是什么样子。我现在才明白归还的是什么。谢谢