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();
我正在尝试通过 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();