原则2:选择实体字段,包括相关字段

时间:2014-12-02 13:48:44

标签: php rest symfony doctrine-orm

我有以下实体:

/**
 * @ORM\Table(name="Employee")
 * 
@ORM\Entity(repositoryClass="Project\BackendBundle\Entity\Repository\EmployeeRepository")
 */
class Employee
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="Division")
     * @ORM\JoinColumn(name="division_id", referencedColumnName="id")
     * @Expose
     **/
    private $division;

    /**
     * @ORM\ManyToOne(targetEntity="Position")
     * @ORM\JoinColumn(name="position_id", referencedColumnName="id")
     */
    private $position;

    .....
}

使用我的REST API,我想在其中放置名为" fields"的过滤器 我想要检索的以逗号分隔的实体字段列表。我也是 希望能够在那里放置相关的字段。所以请求看起来 像这样:

/api/employee?fields=id,division

我检查这些字段,如果它们存在于实体字段或关联映射中。

每个相关字段都会添加到查询中,如下所示:

foreach ( $this->assoc as $key => $mapping ) {
    $queryBuilder
        ->addSelect(substr($key, 0, 1) . ' AS ' . $key)
        ->leftJoin(
            $mapping['targetEntity'],
            substr($key, 0, 1),
            \Doctrine\ORM\Query\Expr\Join::WITH,
            substr($key, 0, 1) . ' = u.' . $key
        );
}

从上面的请求我得到以下DQL:

SELECT u.id, d AS division FROM Project\BackendBundle\Entity\Employee u LEFT JOIN Project\BackendBundle\Entity\Division d WITH d = u.division

一切都很好,我得到了预期的结果(var_dump()):

array (size=1)
  0 => 
    array (size=2)
      'division' => 
        object(Project\BackendBundle\Entity\division)[645]
          private 'id' => int 20
          private 'name' => string 'division1' (length=9)
      'id' => int 890

现在,如果我在请求的字段中再添加一个关联字段:

/api/employee?fields=id,division,position

我得到以下DQL:

SELECT u.id, d AS division, p AS position FROM Project\BackendBundle\Entity\Employee u LEFT JOIN Project\BackendBundle\Entity\Division d WITH d = u.division LEFT JOIN Project\BackendBundle\Entity\Position p WITH p= u.position

结果现在看起来像这样:

array (size=2)
  0 => 
    array (size=1)
      'division' => 
        object(Project\BackendBundle\Entity\Kategorija)[672]
          private 'id' => int 20
          private 'name' => string 'division1' (length=9)
  1 => 
    array (size=2)
      'position' => 
        object(Project\BackendBundle\Entity\Position)[629]
          private 'id' => int 15
          private 'name' => string 'Manager' (length=7)
      'id' => int 890

问题是现在一个实体的结果取而代之的是两个数组 一个。

预期结果是:

array (size=1)
  0 => 
    array (size=3)
      'division' => 
        object(Project\BackendBundle\Entity\Kategorija)[672]
          private 'id' => int 20
          private 'name' => string 'division1' (length=9)
      'position' => 
        object(Project\BackendBundle\Entity\Position)[629]
          private 'id' => int 15
          private 'name' => string 'Manager' (length=7)
      'id' => int 890

我错过了什么或做错了什么?

修改

我发现我的方式错误了。我开始使用PARTIAL功能。

根据请求/api/employee?fields=id,division,DQL如下所示:

SELECT partial u.{id,division} FROM Project\BackendBundle\Entity\Employee u

结果是:

array (size=1)
      0 => 
        array (size=3)
          'division' => 
            object(Project\BackendBundle\Entity\Kategorija)[672]
              private 'id' => int 20
              private 'name' => string 'division1' (length=9)
          'position' => 
            object(Project\BackendBundle\Entity\Position)[629]
              private 'id' => int 15
              private 'name' => string 'Manager' (length=7)
          'id' => int 890

您可以看到我获得了请求的实体字段+所有相关字段,无论我只请求一个关联字段。

如何过滤这些相关字段?

1 个答案:

答案 0 :(得分:0)

您使用什么命令来执行DQL?当您在DQL语句中选择“除法”或“位置”时,它会将其视为完整对象。如果选择division.id和position.id应该可以正常工作。