我使用SonataAdmin
和SonataDoctrineORMAdmin
捆绑来管理实体。
问题是我无法弄清楚如何在列表视图中急切获取相关实体,并且随着列出的实体数量的增加,执行的查询数量也会迅速增加。
我尝试添加`fetch =" EAGER"对于关系注释,但是配置文件显示Sonata无论如何都会执行单独的查询。
这是一段关系代码:
发布
<?php
namespace Acme\AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Table()
* @ORM\Entity
*/
class Post
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="name", type="string", length=255)
**/
private $name;
/**
* @ORM\ManyToMany(targetEntity="Acme\AppBundle\Entity\Tag", fetch="EAGER")
* @ORM\JoinTable(name="join_post_to_tag",
* joinColumns={@ORM\JoinColumn(name="post_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")}
* )
**/
private $tags;
public function getId()
{
return $this->id;
}
public function setName($names)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
public function setTags($tags)
{
$this->tags = $tags;
return $this;
}
public function __toString()
{
return $this->getName();
}
}
标签
<?php
namespace Acme\AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity
*/
class Tag
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="value", type="string", length=255)
*/
private $value;
public function getId()
{
return $this->id;
}
public function setValue($value)
{
$this->value = $value;
return $this;
}
public function getValue()
{
return $this->value;
}
public function __toString()
{
return ($this->getValue()) ? : '';
}
}
运行的第一个相关查询是获取所有帖子:
SELECT DISTINCT p0_.id AS id0, p0_.id AS id1
FROM Post p0_
LEFT JOIN join_post_to_tag j1_ ON p0_.id = j1_.post_id
LEFT JOIN Tag p1_ ON p1_.id = j1_.target_id
ORDER BY p0_.id ASC
但这不会获取相关标签,即使它确实如此,它仍会再次查询:
SELECT t0.id AS id1, t0.value AS value2
FROM Tag t0
INNER JOIN join_post_to_tag ON t0.id = join_post_to_tag.tag_id
WHERE join_post_to_tag.post_id = ?
我试图弄乱管理类中的createQuery
方法,但无法真正找到使相关实体正确获取的方法。
有没有办法强制列表视图急切地获取所需的相关实体?
答案 0 :(得分:1)
您使用createQuery($ context)方法走在正确的轨道上。 我已经实现了以下的热切加载:
public function createQuery($context = 'list')
{
$query = parent::createQuery($context); // let sonata build it's default query for the entity
$rootEntityAlias = $query->getRootAlias(); // get the alias defined by sonata for the root entity
$query->join($rootEntityAlias.'.relationFieldName', 'relationFieldAlias'); // manualy define the join you need
$query->addSelect('relationFieldAlias'); // this is the key line. It is not enough to join a table. You have to also add it to the select list of the query, so that it's actualy fetched
// $query->join(...) // repeat the process of joining and selecting for each relation field you need
// $query->addSelect(...)
return $query; // return the altered query to sonata. this will only work for the "list" action.
}
如果您在使用此功能时遇到问题,请与我联系:)
关于这个主题的进一步阅读:
SO question