Symfony2 计算与另一个实体相关的实体字段 [英] Symfony2 count entity fields that relate to another entity

查看:29
本文介绍了Symfony2 计算与另一个实体相关的实体字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have got 2 entities - Authors and Books, 1 author may have many books. I want to show in a table how many books EACH author has (different number per each author). I`ve already seen this question, also this, and this and tried this, as I thought it would be more elegant solution:

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

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

but every time I get the total number of books for ALL authors. In my controller I get the books like this:

$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>

编辑 2 我的作者实体

EDIT 2 My Author entity

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

编辑 3 本书实体

<?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:

There is no annotations, entities are mapped in *.orm.yml files. 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: {  }

推荐答案

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

You don't need to fetch all books for this so if you don't use the array of all the books in the system somewhere else on this page I'd remove that query (and view param).

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

Then I'd start to clean up some naming.

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

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

An entity is a recipe for how your app will handle one thing, so we'll go with singular names

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

When you create relations in Doctrine you (usually) don't need to set up your own join tables or think about foreign keys (ids) at all. The relations make much more sense to name by entity (as they do in the docs)

所以上面应该是

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

您的作者实体缺少与 Book 实体的关系

Your Author entity is missing a relation to the Book entity

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

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

Note how we in one entity has a relation with a singular name, and in the other we have a relation with a plural name. These names simply makes sense as one author can have many books, but one book can only belong to one author.

因此在您的应用程序中(如果您从这些映射中生成实体)您将获得诸如 $book->getAuthor()$author->getBooks()<之类的方法/code>,它正确地描述了他们做什么以及你可以期望得到什么回报.

So in your app (if you generate entities out of these mappings) you will get methods like $book->getAuthor() and $author->getBooks(), which properly describe what they do and what you can expect to get returned.

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

With the relations in place this should be as simple as:

选择您想要的作者:

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

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

Note $authors instead of $authorids - again since we get authors and not an array of ids. We join in the books (via the relation in the Author entity called "books") to avoid forcing Doctrine to run one or more separate queries later on (relations are lazy loaded if not joined).

然后在 Twig 中我们只需要做

Then in Twig we simply do

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

此处更改的最后一点命名{% for author in author %} 只是错误的方法.指出这点似乎微不足道或愚蠢,但编写干净易懂的代码对于帮助他人(和您自己)理解实际发生的事情至关重要.如果我阅读作者",那么我期待的是一系列作者,而不是包含一位作者信息的对象.

Last bit of naming changed here {% for authors in author %} was simply the wrong way around. It might seem trivial or silly to point out, but writing clean and understandable code is cruical to help others (and yourself) to understand what's actually going on. If I read "authors" then I'm expecting an array of authors, not an object containing the info of one author.

这篇关于Symfony2 计算与另一个实体相关的实体字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆