Doctrine 获取间接关联的对象

Doctrine fetching indirectly associated objects

我正在尝试通过 3 个表(用户、客户、帐户)获取关联对象。 User 与 client 是一对多的关系,client 与 account 是一对多的关系。我使用这个简单的代码轻松获取一个特定用户的所有客户端:

$user = $this->getUser();
$id = $user->getId();
$user = $this->getDoctrine()->getRepository('AcmeUserBundle:User')->find($id);
$clients = $user->getClients();

同样,我可以使用以下代码检索一个特定客户的所有帐户:

$client = $this->getDoctrine()->getRepository('AcmeUserBundle:Client')->find($clientref);
$accounts = $client->getAccounts();

现在想直接获取一个用户的所有账号。我该怎么做?我尝试了以下方法:

$user = $this->getUser();
$id = $user->getId();
$user = $this->getDoctrine()->getRepository('AcmeUserBundle:User')->find($id);
$client = $user->getClients();
$accounts = $client->getAccounts();

但我收到以下错误 'Attempted to call method "getAccounts" on class "Doctrine\ORM\PersistentCollection"'。 我相信我遗漏了一些东西,因为当我获取用户时 "Accounts" 可能不会被 Doctrine 延迟加载,只有 "Clients" 是。实现这一目标的最佳方法是什么?你能给我一个可行的代码示例吗(例如迭代或 DQL 查询)? 谢谢

这是正确的行为。 $user->getClients() 返回一个集合,而不是单个对象。 Doctrine 的集合不代理对其成员的方法调用。有两种方法可以解决您的问题:

比较简单的。依靠 Doctrine 的惰性加载。假设您使用这样的数据:

foreach ($client as $user->getClients()) {
    foreach ($account as $client->getAccounts()) {
        echo $account->getId();
    }
}

ORM 将自动获取帐户,运行 为每个客户单独查询数据库。仅当您不关心性能时才这样做:O(N) 次请求很糟糕。

更好的那个。使用 LEFT JOIN 一次查询数据库即可获取所有数据。

$qb = $this->getDoctrine()->getManager()->createQueryBuilder()
    ->select('u, c, a')
    ->from('AcmeUserBundle:User', 'u')
    ->leftJoin('u.clients', 'c')
    ->leftJoin('c.accounts', 'a')
    ->where('u.id = :id');

$user = $qb->getQuery()
    ->setParameter('id', $id)
    ->getOneOrNullResult();