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

Php 原则2:选择实体字段,包括关联字段,php,rest,symfony,doctrine-orm,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") * @OR

我拥有以下实体:

/**
 * @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;

    .....
}
使用我的RESTAPI,我想制作一个名为“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
        );
}
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
SELECT partial u.{id,division} FROM Project\BackendBundle\Entity\Employee u
我检查这些字段,如果它们存在于实体字段或关联映射中

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

/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
        );
}
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
SELECT partial u.{id,division} FROM Project\BackendBundle\Entity\Employee u
根据上述请求,我得到以下DQL:

SELECT u.id, d AS division FROM Project\BackendBundle\Entity\Employee u LEFT JOIN Project\BackendBundle\Entity\Division d WITH d = u.division
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
一切正常,我得到了预期的结果(
var\u dump()
):

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

/api/employee?fields=id,division,position
我得到以下DQL:

SELECT u.id, d AS division FROM Project\BackendBundle\Entity\Employee u LEFT JOIN Project\BackendBundle\Entity\Division d WITH d = u.division
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
现在的结果如下所示:

/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
        );
}
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
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
我错过了什么或做错了什么

编辑

我发现我把字段弄错了。我开始使用部分功能

根据请求,DQL如下所示:

/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
        );
}
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
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
您可以看到,我得到了请求的实体字段+所有关联字段,无论我只请求了一个关联字段


如何过滤这些相关字段?

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

或者您可以选择所需的员工(无需复杂查询),获取请求的字段名数组,并将其作为序列化组传递给JMS序列化程序(您很可能正在使用它)。此外,您的实体在属性上定义这些组的方式是,position将具有组“position”,id将具有组“id”,依此类推。这样,序列化程序将只从您作为组传递的实体中获取这些属性