我有两个实体——作者和图书,一个作者可能有很多书。我想在表格中显示每个作者有多少本书(每个作者有不同的数量)。我已经看到了这个问题,这个,这个,并尝试了这个,因为我认为这将是一个更优雅的解决方案:
<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>
编辑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;
}
}
编辑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.org.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: { }
Author.orgm.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: { }
您不需要为此获取所有书籍,因此如果您不在此页面的其他位置使用系统中所有书籍的数组,我会删除该查询(并查看参数)。
然后我会开始清理一些命名。
AB'ProjectBundle'Entity'Books:
...
manyToOne:
authorid:
targetEntity: Author
实体是你的应用程序如何处理一件事的配方,所以我们将使用单数名称
当你在Doctrine中创建关系时,你(通常)根本不需要建立自己的联接表或考虑外键(id)。按实体命名关系更有意义(就像在文档中一样)
所以上面应该是
AB'ProjectBundle'Entity'Book:
...
manyToOne:
author:
targetEntity: Author
您的作者实体缺少与图书实体的关系
AB'ProjectBundle'Entity'Author:
...
oneToMany:
books:
targetEntity: Book
注意,我们在一个实体中与单数名称有关系,而在另一个实体上与复数名称有关系。这些名字很有道理,因为一个作者可以有很多书,但一本书只能属于一个作者。
因此,在你的应用程序中(如果你从这些映射中生成实体),你会得到像$book->getAuthor()
和$author->getBooks()
这样的方法,它们正确地描述了它们的作用以及你可以期望返回的内容。
有了关系,这应该很简单:
选择您想要的作者:
$query = $em->createQuery('SELECT a, b FROM AB'ProjectBundle'Entity'Authors a JOIN a.books b');
$authors = $query->getResult();
注意$authors而不是$authorids——同样,因为我们得到的是authors,而不是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 %}
只是错误的方式。指出这一点可能显得微不足道或愚蠢,但编写干净易懂的代码对于帮助他人(和你自己)了解实际情况是至关重要的。如果我读"authors",那么我期待的是一组作者,而不是一个包含一个作者信息的对象。