使用原则

时间:2017-03-19 16:57:14

标签: php laravel laravel-5 doctrine-orm

我正在尝试使用带有laravel的Doctrine,我能够完成所有映射并返回一些结果。但问题在于一对多的关系,即多边的ArrayCollection是空的。

我有两个类Project和Client,一个Client有很多Project。在项目列表中,我确实成功返回客户端,但是在客户端,Project数组是空的。这是我总结的客户端类:

<?php
namespace CodeProject\Entities\Doctrine;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="clients")
 */
class Client implements \JsonSerializable {

     /**
      * @ORM\Column(type="integer")
      * @ORM\Id
      * @ORM\GeneratedValue(strategy="AUTO")
      */
     private $id;

    /**
     *
     * @ORM\OneToMany(targetEntity="Project", mappedBy="client")
     */
    private $projects;

    public function __construct() {
        $this->projects = new ArrayCollection();
    }
}

现在汇总了Project类:

<?php

namespace CodeProject\Entities\Doctrine;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="projects")
 */
class Project implements \JsonSerializable {

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * 
     * @ORM\ManyToOne(targetEntity="Client", inversedBy="projects")
     * @ORM\JoinColumn(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 Drives\nLake 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 Drives\nLake 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": {}
        }
    }
]

我错过了什么?

更新

我的ClientRepository:

<?php

namespace CodeProject\Repositories;

use Doctrine\ORM\EntityRepository;

class ClientRepositoryDoctrine extends EntityRepository {

    public function getProjects($id) {
        $client = $this->find($id);
        return $client->getProjects();
    }

}

我的ClientController在列出某个客户的项目的函数中:

public function listProjects($id){
    return response()->json($this->repository->getProjects($id));
}

即便如此,它也没有列出任何内容。

使用fetch join在我的存储库中尝试使用DQL:

<?php

namespace CodeProject\Repositories;

use Doctrine\ORM\EntityRepository;

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 Parkway\nMireyabury, 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": {}
    }
]

1 个答案:

答案 0 :(得分:1)

听起来你永远不会加载关系。默认情况下,OneToMany关系会延迟加载。

您可以通过对其执行任何需要数据库调用的操作来触发加载。在这个例子中,一个简单的foreach就足够了。

foreach($client->getProjects() as $project) {
    // ...
}

您还可以将关系配置为急切加载。资料来源:21.2.26. @OneToMany

/**
 * @OneToMany(..., fetch="EAGER")
 **/

这也可以是每个DQL查询。资料来源:14.2.2. Joins

SELECT c, c.projects FROM Client c

关于Project.client的加载,可以是实体地图。您已经从实体管理器加载了客户端,因此当项目实例显示&#34;我有client_id = 1&#34;您的实体管理员注意到客户端#1已经加载,并将其与Project.client关系相关联。

另一种方式是不可能的,因为Doctrine无法知道您已经加载了客户可以拥有的所有可能的项目。找出的唯一真正方法是查询数据库。