我正在尝试将Doctrine与laravel一起使用,我能够进行所有映射并返回一些结果。但问题在于一对多关系,即多方 ArrayCollection 是空的。
我有两个类项目和客户,一个客户有很多项目。在项目列表中,我确实成功返回了客户端,但是在客户端,项目数组为空。以下是我总结的客户端类:
<?php
namespace CodeProjectEntitiesDoctrine;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity
* @ORMTable(name="clients")
*/
class Client implements JsonSerializable {
/**
* @ORMColumn(type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* @ORMOneToMany(targetEntity="Project", mappedBy="client")
*/
private $projects;
public function __construct() {
$this->projects = new ArrayCollection();
}
}
现在总结的项目类:
<?php
namespace CodeProjectEntitiesDoctrine;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity
* @ORMTable(name="projects")
*/
class Project implements JsonSerializable {
/**
* @ORMColumn(type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* @ORMManyToOne(targetEntity="Client", inversedBy="projects")
* @ORMJoinColumn(name="client_id", referencedColumnName="id")
*/
private $client;
}
当我访问控制器以带来有关客户端的信息时,这是返回的内容,请注意项目是一个空数组:
[
{
"id": 21,
"name": "Dolores Osinski",
"responsible": "Ashton Conn",
"email": "Crist.Mario@gmail.com",
"phone": "(936)177-7976",
"address": "80311 Rossie DrivesnLake Brandyn, KS 39255-7560",
"obs": "Aliquid harum architecto eum natus qui.",
"created_at": "2017-03-19 16:33:39",
"updated_at": "2017-03-19 16:33:39",
"projects": {}
}
]
在项目方面,我得到了客户端,如您所见:
[
{
"id": 1,
"name": "tenetur",
"description": "Animi ut enim voluptas. Provident alias aut animi nemo repellendus. A dolores magni ducimus sit ex.",
"progress": "39.00",
"status": 4,
"due_date": "1972-10-26 12:56:38",
"created_at": "2017-03-19 16:33:45",
"updated_at": "2017-03-19 16:33:45",
"client": {
"id": 21,
"name": "Dolores Osinski",
"responsible": "Ashton Conn",
"email": "Crist.Mario@gmail.com",
"phone": "(936)177-7976",
"address": "80311 Rossie DrivesnLake Brandyn, KS 39255-7560",
"obs": "Aliquid harum architecto eum natus qui.",
"created_at": "2017-03-19 16:33:39",
"updated_at": "2017-03-19 16:33:39",
"projects": {}
}
}
]
我错过了什么?
更新
我的客户端存储库:
<?php
namespace CodeProjectRepositories;
use DoctrineORMEntityRepository;
class ClientRepositoryDoctrine extends EntityRepository {
public function getProjects($id) {
$client = $this->find($id);
return $client->getProjects();
}
}
我的客户端控制器在列出某个客户端的项目的函数中:
public function listProjects($id){
return response()->json($this->repository->getProjects($id));
}
即使这样,它也不会列出任何内容。
在我的存储库中尝试使用 DQL 并加入 fetch 连接:
<?php
namespace CodeProjectRepositories;
use DoctrineORMEntityRepository;
class ClientRepositoryDoctrine extends EntityRepository {
public function getProjects($id) {
$result = $this->getEntityManager()->createQueryBuilder()->
select('c, p')->
from('CodeProject:Client', 'c')->
join('c.projects', 'p')->
where('c.id = :id')->
setParameter(':id', $id)->getQuery()->getResult();
return $result;
}
}
我明白了,即使使用 fetch join 强制加载项目,项目仍然是空的:
[
{
"id": 1,
"name": "Mariam Jast",
"responsible": "Imogene Schowalter",
"email": "wHackett@gmail.com",
"phone": "05482413294",
"address": "062 Block ParkwaynMireyabury, KS 63554-2056",
"obs": "Occaecati aperiam quibusdam maxime laboriosam aperiam sint.",
"created_at": "2017-03-20 02:29:47",
"updated_at": "2017-03-20 02:29:47",
"projects": {}
}
]
听起来你从来没有加载过关系。默认情况下,一对多关系是延迟加载的。
您可以通过对加载执行任何需要数据库调用的操作来触发加载。在这个例子中,一个简单的foreach就足够了。
foreach($client->getProjects() as $project) {
// ...
}
您还可以将关系配置为预先加载。资料来源:21.2.26。@OneToMany
/**
* @OneToMany(..., fetch="EAGER")
**/
这也可以是每个 DQL 查询。来源:14.2.2。加入
SELECT c, c.projects FROM Client c
关于Project.client的加载,这可能是实际的实体映射。您已经从实体管理器加载了客户端,因此当项目实例显示"我有 client_id = 1"时,您的实体管理器会注意到客户端 #1 已加载,并将其与 Project.client 关系相关联。
另一种方式是不可能的,因为Doctrine无法知道你已经加载了客户可以拥有的所有可能的项目。找出答案的唯一真正方法是查询数据库。