【问题标题】:Symfony2 count entity fields that relate to another entitySymfony2 计算与另一个实体相关的实体字段
【发布时间】:2016-07-14 23:57:53
【问题描述】:

我有 2 个实体 - Authors 和 Books,1 个作者可能有很多书。我想在表格中显示每个作者有多少本书(每个作者的数量不同)。我已经看到this 问题,还有thisthis 并尝试了这个,因为我认为这会是更优雅的解决方案:

<td>{{books|length}}</td>

但每次我得到所有作者的书籍总数。在我的控制器中,我得到这样的书:

$query = $em->createQuery('SELECT b FROM AB\ProjectBundle\Entity\Books u WHERE b.authorid in (:authorids)');
$query->setParameter('authorid',$authorids);
$books = $query->getResult();

作者是这样选择的:

$query = $em->createQuery('SELECT a FROM AB\ProjectBundle\Entity\Authors a');
$authorids = $query->getResult();

编辑:我的树枝循环

<tbody>
            {% for authors in author %}
        <tr>
            <td>{{ authors.name }}</td>
            <td>{{ authors.isactive }}</td>         
            <td>{{ books.authorid|length}}</td>
        </tr>
            {% endfor %}
</tbody>

EDIT 2 我的作者实体

class Author
{
    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * Set name
     *
     * @param string $name
     * @return string
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
}

EDIT 3 Books 实体

<?php

namespace AB\ProjectBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * 
 */
class Books
{
    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * @var \AB\ProjectBundle\Entity\Author
     */
    private $authorid;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set Authorid
     *
     * @param \AB\ProjectBundle\Entity\Author $authorid
     * @return Author
     */
    public function setAuthorid(\AB\ProjectBundle\Entity\Author $authorid = null)
    {
        $this->authorid = $authorid;

    return $this;
    }

    /**
     * Get Authorid
     *
     * @return \AB\ProjectBundle\Entity\Author
     */
    public function getAuthorid()
    {
        return $this->authorid;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return string
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
}

没有注释,实体映射在 *.orm.yml 文件中。 Book.orm.yml:

AB\ProjectBundle\Entity\Books:
type: entity
table: Books
id:
    id:
        type: integer
        nullable: false
        unsigned: false
        id: true
        generator:
            strategy: IDENTITY
fields:
    name:
        type: text
        nullable: false

manyToOne:
    authorid:
        targetEntity: Author
        cascade: {  }
        mappedBy: null
        inversedBy: null
        joinColumns:
            authorid:
                referencedColumnName: id
        orphanRemoval: false
lifecycleCallbacks: {  }

作者.orm.yml

AB\ProjectBundle\Entity\Author:
type: entity
table: Author
id:
    id:
        type: integer
        nullable: false
        unsigned: false
        id: true
        generator:
            strategy: IDENTITY
fields:
    name:
        type: text
        nullable: false
lifecycleCallbacks: {  }

【问题讨论】:

  • Author 和 Book 实体有实际关系吗?如果是这样,您可以这样做 {{ author.books|length }} (其中“books”是您在 Author 实体中命名的 Book 关系)
  • 是的,有一个实际的关系,但我仍然继续获得所有书籍的总数。我只是不能告诉它分别显示与每个作者相关的书籍数量((
  • 你能在输出作者/书籍信息的地方添加树枝循环吗?
  • 当我得到书籍的总数并尝试使用它的一些属性(比如 authorid)时,我得到一个错误“Key 'authorid' for array with keys 0,1,2,3,我的树枝模板中不存在 4 等"
  • 向我们展示您的作者实体

标签: php symfony


【解决方案1】:

您不需要为此获取所有书籍,因此如果您不在此页面的其他位置使用系统中所有书籍的数组,我将删除该查询(并查看参数)。

然后我会开始清理一些命名。

AB\ProjectBundle\Entity\Books:
...
manyToOne:
    authorid:
        targetEntity: Author

实体是您的应用如何处理一件事的秘诀,因此我们将使用单数名称

当您在 Doctrine 中创建关系时,您(通常)根本不需要设置自己的连接表或考虑外键(id)。通过实体命名关系更有意义(就像在文档中所做的那样)

所以上面应该是

AB\ProjectBundle\Entity\Book:
...
manyToOne:
    author:
        targetEntity: Author

您的 Author 实体缺少与 Book 实体的关系

AB\ProjectBundle\Entity\Author:
...
oneToMany:
    books:
        targetEntity: Book

注意我们如何在一个实体中与单数名称有关系,而在另一个实体中我们与复数名称有关系。这些名称很有意义,因为一位作者可以拥有多本书,但一本书只能属于一位作者。

因此,在您的应用中(如果您从这些映射中生成实体),您将获得像 $book-&gt;getAuthor()$author-&gt;getBooks() 这样的方法,它们正确地描述了它们的作用以及您期望得到的返回值。


有了适当的关系,这应该很简单:

选择你想要的作者:

$query = $em->createQuery('SELECT a, b FROM AB\ProjectBundle\Entity\Authors a JOIN a.books b');
$authors = $query->getResult();

注意 $authors 而不是 $authorids - 因为我们得到的是作者而不是一个 id 数组。我们加入书籍(通过 Author 实体中称为“书籍”的关系)以避免强制 Doctrine 稍后运行一个或多个单独的查询(如果未加入关系,则延迟加载)。

然后在 Twig 中我们简单地做

 <tbody>
        {% for author in authors %}
    <tr>
        <td>{{ author.name }}</td>
        <td>{{ author.isactive }}</td>         
        <td>{{ author.books|length}}</td>
    </tr>
        {% endfor %}
 </tbody>

这里的最后一点命名更改{% for authors in author %} 完全是错误的方式。指出这似乎微不足道或愚蠢,但编写干净且易于理解的代码对于帮助他人(和您自己)理解实际发生的事情至关重要。如果我阅读“作者”,那么我期待的是一组作者,而不是包含一个作者信息的对象。

【讨论】:

  • 按预期工作))非常感谢您的帮助!
  • 太好了,希望有意义:)
  • 优秀的答案!详细而准确的解释! +1
  • 我宁愿得到这样的作者:$em-&gt;getRepository('APProjectBundle:Author")-&gt;findAll().
  • @cezar 我同意 - 不同意。查询应该在存储库中,而不是在控制器中 - 是的。但是默认的findAll() 查询将不包括书籍,因此如果您像我们在 Twig 中那样在 for 循环中获取它们,您将强制 Doctrine 运行 n+1 个查询(它将为每个作者从作者查询中运行一个选择书籍在循环)。您可以覆盖 findAll 方法,或将书籍关系设置为预加载,但我更建议创建自定义 findAllWithBooks 方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 2020-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多