学说从集合中获取所有实体

Doctrine get all entities from collection

我不知道我正在尝试的是否真的可行。所以我想问问你们。

我想做什么:

在代码中:

$companyIds = array(1,2,3);
$companies = $this->em->getRepository('AppBundle:Company')->findById($companyIds);
dump($companies->getUsers()); // this will not work, but I like it to work

它们的关联如下:

class User implements AdvancedUserInterface, \Serializable
{
  /**
   * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Company", inversedBy="users")
   * @ORM\JoinColumn(name="company_id", referencedColumnName="id", nullable=false)
   */
  private $company;
}

class Company
{
    /**
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\User", mappedBy="company")
     */
    private $users;
}

存储库 returns 您是 ArrayCollection 个实体,而不是单个实体,因此您需要分别访问每个实体。

这应该有效:

foreach($companies as $company) {
    $company->getUsers();
}

上面的问题是,默认情况下,它会在单独的查询中(在调用 getUsers 时按需)从每个公司的数据库中获取(延迟加载)用户,这在大规模情况下效率很低.

根据您的需要,有几种可能的解决方案。

您可以将 doctrine 配置为始终获取带有公司的用户,这称为预先获取。

获取用户后,您可以合并 ArrayCollections(并在需要时删除重复项),以实现包含所有用户的单个集合。

其他方法可能是通过在您公司存储库的自定义方法中创建足够的 DQL 查询来获取有用户的公司。如果您只需要用户而不需要公司,那么它可能是一个只获取没有公司的用户的查询。

您可以例如使用一个查询获取所有 Comapany 个包含用户的实体:

$companies = $em->createQueryBuilder()
  ->select('c, u')
  ->from('AppBundle:Company', 'c')
  // or left join based on you needs
  ->innerJoin('c.users', 'u')
  ->getQuery()
  ->getResult();

这不会在获取公司用户时产生查询。

在您的用户存储库中尝试这样的操作:

public function getAllUsersFromCompanies($ids)
{
    $qb = $this->createQueryBuilder('u');
    $qb->leftJoin('u.company', 'c')
       ->where('c.id IN :ids')
       ->setParameter('ids', $ids)
       ->getQuery();

        return $query->getResult();
}

我们在此处将用户 table 与公司 table 合并,这为我们提供了每个用户的公司。然后,我们过滤掉每个拥有错误公司的用户。